| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230 |
- //-----------------------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Diagnostics;
- using System.Runtime;
- using System.ServiceModel;
- using System.ServiceModel.Diagnostics;
- using System.ServiceModel.Diagnostics.Application;
- public abstract class CommunicationObject : ICommunicationObject
- {
- bool aborted;
- bool closeCalled;
- #if DEBUG
- StackTrace closeStack;
- StackTrace faultedStack;
- #endif
- ExceptionQueue exceptionQueue;
- object mutex;
- bool onClosingCalled;
- bool onClosedCalled;
- bool onOpeningCalled;
- bool onOpenedCalled;
- bool raisedClosed;
- bool raisedClosing;
- bool raisedFaulted;
- bool traceOpenAndClose;
- object eventSender;
- CommunicationState state;
- protected CommunicationObject()
- : this(new object())
- {
- }
- protected CommunicationObject(object mutex)
- {
- this.mutex = mutex;
- this.eventSender = this;
- this.state = CommunicationState.Created;
- }
- internal CommunicationObject(object mutex, object eventSender)
- {
- this.mutex = mutex;
- this.eventSender = eventSender;
- this.state = CommunicationState.Created;
- }
- internal bool Aborted
- {
- get { return this.aborted; }
- }
- internal object EventSender
- {
- get { return this.eventSender; }
- set { eventSender = value; }
- }
- protected bool IsDisposed
- {
- get { return this.state == CommunicationState.Closed; }
- }
- public CommunicationState State
- {
- get { return this.state; }
- }
- protected object ThisLock
- {
- get { return this.mutex; }
- }
- protected abstract TimeSpan DefaultCloseTimeout { get; }
- protected abstract TimeSpan DefaultOpenTimeout { get; }
- internal TimeSpan InternalCloseTimeout
- {
- get { return this.DefaultCloseTimeout; }
- }
- internal TimeSpan InternalOpenTimeout
- {
- get { return this.DefaultOpenTimeout; }
- }
- public event EventHandler Closed;
- public event EventHandler Closing;
- public event EventHandler Faulted;
- public event EventHandler Opened;
- public event EventHandler Opening;
- public void Abort()
- {
- lock (ThisLock)
- {
- if (this.aborted || this.state == CommunicationState.Closed)
- return;
- this.aborted = true;
- #if DEBUG
- if (closeStack == null)
- closeStack = new StackTrace();
- #endif
- this.state = CommunicationState.Closing;
- }
- if (DiagnosticUtility.ShouldTraceInformation)
- {
- TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.CommunicationObjectAborted, SR.GetString(SR.TraceCodeCommunicationObjectAborted, TraceUtility.CreateSourceString(this)), this);
- }
- bool throwing = true;
- try
- {
- OnClosing();
- if (!this.onClosingCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, this);
- OnAbort();
- OnClosed();
- if (!this.onClosedCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosed"), Guid.Empty, this);
- throwing = false;
- }
- finally
- {
- if (throwing)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectAbortFailed, SR.GetString(SR.TraceCodeCommunicationObjectAbortFailed, this.GetCommunicationObjectType().ToString()), this);
- }
- }
- }
- public IAsyncResult BeginClose(AsyncCallback callback, object state)
- {
- return this.BeginClose(this.DefaultCloseTimeout, callback, state);
- }
- public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
- {
- if (timeout < TimeSpan.Zero)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
- using (DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? this.CreateCloseActivity() : null)
- {
- CommunicationState originalState;
- lock (ThisLock)
- {
- originalState = this.state;
- #if DEBUG
- if (closeStack == null)
- closeStack = new StackTrace();
- #endif
- if (originalState != CommunicationState.Closed)
- this.state = CommunicationState.Closing;
- this.closeCalled = true;
- }
- switch (originalState)
- {
- case CommunicationState.Created:
- case CommunicationState.Opening:
- case CommunicationState.Faulted:
- this.Abort();
- if (originalState == CommunicationState.Faulted)
- {
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- }
- return new AlreadyClosedAsyncResult(callback, state);
- case CommunicationState.Opened:
- {
- bool throwing = true;
- try
- {
- OnClosing();
- if (!this.onClosingCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, this);
- IAsyncResult result = new CloseAsyncResult(this, timeout, callback, state);
- throwing = false;
- return result;
- }
- finally
- {
- if (throwing)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectCloseFailed, SR.GetString(SR.TraceCodeCommunicationObjectCloseFailed, this.GetCommunicationObjectType().ToString()), this);
- }
- Abort();
- }
- }
- }
- case CommunicationState.Closing:
- case CommunicationState.Closed:
- return new AlreadyClosedAsyncResult(callback, state);
- default:
- throw Fx.AssertAndThrow("CommunicationObject.BeginClose: Unknown CommunicationState");
- }
- }
- }
- public IAsyncResult BeginOpen(AsyncCallback callback, object state)
- {
- return this.BeginOpen(this.DefaultOpenTimeout, callback, state);
- }
- public IAsyncResult BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
- {
- if (timeout < TimeSpan.Zero)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
- lock (ThisLock)
- {
- ThrowIfDisposedOrImmutable();
- this.state = CommunicationState.Opening;
- }
- bool throwing = true;
- try
- {
- OnOpening();
- if (!this.onOpeningCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpening"), Guid.Empty, this);
- IAsyncResult result = new OpenAsyncResult(this, timeout, callback, state);
- throwing = false;
- return result;
- }
- finally
- {
- if (throwing)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectOpenFailed, SR.GetString(SR.TraceCodeCommunicationObjectOpenFailed, this.GetCommunicationObjectType().ToString()), this);
- }
- Fault();
- }
- }
- }
- public void Close()
- {
- this.Close(this.DefaultCloseTimeout);
- }
- public void Close(TimeSpan timeout)
- {
- if (timeout < TimeSpan.Zero)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
- using (DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? this.CreateCloseActivity() : null)
- {
- CommunicationState originalState;
- lock (ThisLock)
- {
- originalState = this.state;
- #if DEBUG
- if (closeStack == null)
- closeStack = new StackTrace();
- #endif
- if (originalState != CommunicationState.Closed)
- this.state = CommunicationState.Closing;
- this.closeCalled = true;
- }
- switch (originalState)
- {
- case CommunicationState.Created:
- case CommunicationState.Opening:
- case CommunicationState.Faulted:
- this.Abort();
- if (originalState == CommunicationState.Faulted)
- {
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- }
- break;
- case CommunicationState.Opened:
- {
- bool throwing = true;
- try
- {
- TimeoutHelper actualTimeout = new TimeoutHelper(timeout);
- OnClosing();
- if (!this.onClosingCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosing"), Guid.Empty, this);
- OnClose(actualTimeout.RemainingTime());
- OnClosed();
- if (!this.onClosedCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnClosed"), Guid.Empty, this);
- throwing = false;
- }
- finally
- {
- if (throwing)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectCloseFailed, SR.GetString(SR.TraceCodeCommunicationObjectCloseFailed, this.GetCommunicationObjectType().ToString()), this);
- }
- Abort();
- }
- }
- break;
- }
- case CommunicationState.Closing:
- case CommunicationState.Closed:
- break;
- default:
- throw Fx.AssertAndThrow("CommunicationObject.BeginClose: Unknown CommunicationState");
- }
- }
- }
- Exception CreateNotOpenException()
- {
- return new InvalidOperationException(SR.GetString(SR.CommunicationObjectCannotBeUsed, this.GetCommunicationObjectType().ToString(), this.state.ToString()));
- }
- Exception CreateImmutableException()
- {
- return new InvalidOperationException(SR.GetString(SR.CommunicationObjectCannotBeModifiedInState, this.GetCommunicationObjectType().ToString(), this.state.ToString()));
- }
- Exception CreateBaseClassMethodNotCalledException(string method)
- {
- return new InvalidOperationException(SR.GetString(SR.CommunicationObjectBaseClassMethodNotCalled, this.GetCommunicationObjectType().ToString(), method));
- }
- internal Exception CreateClosedException()
- {
- if (!this.closeCalled)
- {
- return CreateAbortedException();
- }
- else
- {
- #if DEBUG
- string originalStack = closeStack.ToString().Replace("\r\n", "\r\n ");
- return new ObjectDisposedException(this.GetCommunicationObjectType().ToString() + ", Object already closed:\r\n " + originalStack);
- #else
- return new ObjectDisposedException(this.GetCommunicationObjectType().ToString());
- #endif
- }
- }
- internal Exception CreateFaultedException()
- {
- #if DEBUG
- string originalStack = faultedStack.ToString().Replace("\r\n", "\r\n ");
- string message = SR.GetString(SR.CommunicationObjectFaultedStack2, this.GetCommunicationObjectType().ToString(), originalStack);
- #else
- string message = SR.GetString(SR.CommunicationObjectFaulted1, this.GetCommunicationObjectType().ToString());
- #endif
- return new CommunicationObjectFaultedException(message);
- }
- internal Exception CreateAbortedException()
- {
- #if DEBUG
- string originalStack = closeStack.ToString().Replace("\r\n", "\r\n ");
- return new CommunicationObjectAbortedException(SR.GetString(SR.CommunicationObjectAbortedStack2, this.GetCommunicationObjectType().ToString(), originalStack));
- #else
- return new CommunicationObjectAbortedException(SR.GetString(SR.CommunicationObjectAborted1, this.GetCommunicationObjectType().ToString()));
- #endif
- }
- internal virtual string CloseActivityName
- {
- get { return SR.GetString(SR.ActivityClose, this.GetType().FullName); }
- }
- internal virtual string OpenActivityName
- {
- get { return SR.GetString(SR.ActivityOpen, this.GetType().FullName); }
- }
- internal virtual ActivityType OpenActivityType
- {
- get { return ActivityType.Open; }
- }
- ServiceModelActivity CreateCloseActivity()
- {
- ServiceModelActivity retval = null;
- retval = ServiceModelActivity.CreateBoundedActivity();
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(retval, this.CloseActivityName, ActivityType.Close);
- }
- return retval;
- }
- internal bool DoneReceivingInCurrentState()
- {
- this.ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- case CommunicationState.Opening:
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- case CommunicationState.Opened:
- return false;
- case CommunicationState.Closing:
- return true;
- case CommunicationState.Closed:
- return true;
- case CommunicationState.Faulted:
- return true;
- default:
- throw Fx.AssertAndThrow("DoneReceivingInCurrentState: Unknown CommunicationObject.state");
- }
- }
- public void EndClose(IAsyncResult result)
- {
- if (result is AlreadyClosedAsyncResult)
- AlreadyClosedAsyncResult.End(result);
- else
- CloseAsyncResult.End(result);
- }
- public void EndOpen(IAsyncResult result)
- {
- OpenAsyncResult.End(result);
- }
- protected void Fault()
- {
- lock (ThisLock)
- {
- if (this.state == CommunicationState.Closed || this.state == CommunicationState.Closing)
- return;
- if (this.state == CommunicationState.Faulted)
- return;
- #if DEBUG
- if (faultedStack == null)
- faultedStack = new StackTrace();
- #endif
- this.state = CommunicationState.Faulted;
- }
- OnFaulted();
- }
- internal void Fault(Exception exception)
- {
- lock (this.ThisLock)
- {
- if (this.exceptionQueue == null)
- this.exceptionQueue = new ExceptionQueue(this.ThisLock);
- }
- if (exception != null && DiagnosticUtility.ShouldTraceInformation)
- {
- TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.CommunicationObjectFaultReason,
- SR.GetString(SR.TraceCodeCommunicationObjectFaultReason), exception, null);
- }
- this.exceptionQueue.AddException(exception);
- this.Fault();
- }
- internal void AddPendingException(Exception exception)
- {
- lock (this.ThisLock)
- {
- if (this.exceptionQueue == null)
- this.exceptionQueue = new ExceptionQueue(this.ThisLock);
- }
- this.exceptionQueue.AddException(exception);
- }
- internal Exception GetPendingException()
- {
- CommunicationState currentState = this.state;
- Fx.Assert(currentState == CommunicationState.Closing || currentState == CommunicationState.Closed || currentState == CommunicationState.Faulted,
- "CommunicationObject.GetPendingException(currentState == CommunicationState.Closing || currentState == CommunicationState.Closed || currentState == CommunicationState.Faulted)");
- ExceptionQueue queue = this.exceptionQueue;
- if (queue != null)
- {
- return queue.GetException();
- }
- else
- {
- return null;
- }
- }
- // Terminal is loosely defined as an interruption to close or a fault.
- internal Exception GetTerminalException()
- {
- Exception exception = this.GetPendingException();
- if (exception != null)
- {
- return exception;
- }
- switch (this.state)
- {
- case CommunicationState.Closing:
- case CommunicationState.Closed:
- return new CommunicationException(SR.GetString(SR.CommunicationObjectCloseInterrupted1, this.GetCommunicationObjectType().ToString()));
- case CommunicationState.Faulted:
- return this.CreateFaultedException();
- default:
- throw Fx.AssertAndThrow("GetTerminalException: Invalid CommunicationObject.state");
- }
- }
- public void Open()
- {
- this.Open(this.DefaultOpenTimeout);
- }
- public void Open(TimeSpan timeout)
- {
- if (timeout < TimeSpan.Zero)
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
- new ArgumentOutOfRangeException("timeout", SR.GetString(SR.SFxTimeoutOutOfRange0)));
- using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity && this.TraceOpenAndClose ? ServiceModelActivity.CreateBoundedActivity() : null)
- {
- if (DiagnosticUtility.ShouldUseActivity)
- {
- ServiceModelActivity.Start(activity, this.OpenActivityName, this.OpenActivityType);
- }
- lock (ThisLock)
- {
- ThrowIfDisposedOrImmutable();
- this.state = CommunicationState.Opening;
- }
- bool throwing = true;
- try
- {
- TimeoutHelper actualTimeout = new TimeoutHelper(timeout);
- OnOpening();
- if (!this.onOpeningCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpening"), Guid.Empty, this);
- OnOpen(actualTimeout.RemainingTime());
- OnOpened();
- if (!this.onOpenedCalled)
- throw TraceUtility.ThrowHelperError(this.CreateBaseClassMethodNotCalledException("OnOpened"), Guid.Empty, this);
- throwing = false;
- }
- finally
- {
- if (throwing)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectOpenFailed, SR.GetString(SR.TraceCodeCommunicationObjectOpenFailed, this.GetCommunicationObjectType().ToString()), this);
- }
- Fault();
- }
- }
- }
- }
- protected virtual void OnClosed()
- {
- this.onClosedCalled = true;
- lock (ThisLock)
- {
- if (this.raisedClosed)
- return;
- this.raisedClosed = true;
- this.state = CommunicationState.Closed;
- }
- if (DiagnosticUtility.ShouldTraceVerbose)
- {
- TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectClosed, SR.GetString(SR.TraceCodeCommunicationObjectClosed, TraceUtility.CreateSourceString(this)), this);
- }
- EventHandler handler = Closed;
- if (handler != null)
- {
- try
- {
- handler(eventSender, EventArgs.Empty);
- }
- catch (Exception exception)
- {
- if (Fx.IsFatal(exception))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
- }
- }
- }
- protected virtual void OnClosing()
- {
- this.onClosingCalled = true;
- lock (ThisLock)
- {
- if (this.raisedClosing)
- return;
- this.raisedClosing = true;
- }
- if (DiagnosticUtility.ShouldTraceVerbose)
- {
- TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectClosing, SR.GetString(SR.TraceCodeCommunicationObjectClosing, TraceUtility.CreateSourceString(this)), this);
- }
- EventHandler handler = Closing;
- if (handler != null)
- {
- try
- {
- handler(eventSender, EventArgs.Empty);
- }
- catch (Exception exception)
- {
- if (Fx.IsFatal(exception))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
- }
- }
- }
- protected virtual void OnFaulted()
- {
- lock (ThisLock)
- {
- if (this.raisedFaulted)
- return;
- this.raisedFaulted = true;
- }
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectFaulted, SR.GetString(SR.TraceCodeCommunicationObjectFaulted, this.GetCommunicationObjectType().ToString()), this);
- }
- EventHandler handler = Faulted;
- if (handler != null)
- {
- try
- {
- handler(eventSender, EventArgs.Empty);
- }
- catch (Exception exception)
- {
- if (Fx.IsFatal(exception))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
- }
- }
- }
- protected virtual void OnOpened()
- {
- this.onOpenedCalled = true;
- lock (ThisLock)
- {
- if (this.aborted || this.state != CommunicationState.Opening)
- return;
- this.state = CommunicationState.Opened;
- }
- if (DiagnosticUtility.ShouldTraceVerbose)
- TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectOpened, SR.GetString(SR.TraceCodeCommunicationObjectOpened, TraceUtility.CreateSourceString(this)), this);
- EventHandler handler = Opened;
- if (handler != null)
- {
- try
- {
- handler(eventSender, EventArgs.Empty);
- }
- catch (Exception exception)
- {
- if (Fx.IsFatal(exception))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
- }
- }
- }
- protected virtual void OnOpening()
- {
- this.onOpeningCalled = true;
- if (DiagnosticUtility.ShouldTraceVerbose)
- {
- TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.CommunicationObjectOpening, SR.GetString(SR.TraceCodeCommunicationObjectOpening, TraceUtility.CreateSourceString(this)), this);
- }
- EventHandler handler = Opening;
- if (handler != null)
- {
- try
- {
- handler(eventSender, EventArgs.Empty);
- }
- catch (Exception exception)
- {
- if (Fx.IsFatal(exception))
- throw;
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperCallback(exception);
- }
- }
- }
- internal void ThrowIfFaulted()
- {
- this.ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- break;
- case CommunicationState.Opening:
- break;
- case CommunicationState.Opened:
- break;
- case CommunicationState.Closing:
- break;
- case CommunicationState.Closed:
- break;
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfFaulted: Unknown CommunicationObject.state");
- }
- }
- internal void ThrowIfAborted()
- {
- if (this.aborted && !this.closeCalled)
- {
- throw TraceUtility.ThrowHelperError(CreateAbortedException(), Guid.Empty, this);
- }
- }
- internal bool TraceOpenAndClose
- {
- get
- {
- return this.traceOpenAndClose;
- }
- set
- {
- this.traceOpenAndClose = value && DiagnosticUtility.ShouldUseActivity;
- }
- }
- internal void ThrowIfClosed()
- {
- ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- break;
- case CommunicationState.Opening:
- break;
- case CommunicationState.Opened:
- break;
- case CommunicationState.Closing:
- break;
- case CommunicationState.Closed:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfClosed: Unknown CommunicationObject.state");
- }
- }
- protected virtual Type GetCommunicationObjectType()
- {
- return this.GetType();
- }
- protected internal void ThrowIfDisposed()
- {
- ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- break;
- case CommunicationState.Opening:
- break;
- case CommunicationState.Opened:
- break;
- case CommunicationState.Closing:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Closed:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfDisposed: Unknown CommunicationObject.state");
- }
- }
- internal void ThrowIfClosedOrOpened()
- {
- ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- break;
- case CommunicationState.Opening:
- break;
- case CommunicationState.Opened:
- throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);
- case CommunicationState.Closing:
- throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);
- case CommunicationState.Closed:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfClosedOrOpened: Unknown CommunicationObject.state");
- }
- }
- protected internal void ThrowIfDisposedOrImmutable()
- {
- ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- break;
- case CommunicationState.Opening:
- throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);
- case CommunicationState.Opened:
- throw TraceUtility.ThrowHelperError(this.CreateImmutableException(), Guid.Empty, this);
- case CommunicationState.Closing:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Closed:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfDisposedOrImmutable: Unknown CommunicationObject.state");
- }
- }
- protected internal void ThrowIfDisposedOrNotOpen()
- {
- ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- case CommunicationState.Opening:
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- case CommunicationState.Opened:
- break;
- case CommunicationState.Closing:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Closed:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfDisposedOrNotOpen: Unknown CommunicationObject.state");
- }
- }
- internal void ThrowIfNotOpened()
- {
- if (this.state == CommunicationState.Created || this.state == CommunicationState.Opening)
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- }
- internal void ThrowIfClosedOrNotOpen()
- {
- ThrowPending();
- switch (this.state)
- {
- case CommunicationState.Created:
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- case CommunicationState.Opening:
- throw TraceUtility.ThrowHelperError(this.CreateNotOpenException(), Guid.Empty, this);
- case CommunicationState.Opened:
- break;
- case CommunicationState.Closing:
- break;
- case CommunicationState.Closed:
- throw TraceUtility.ThrowHelperError(this.CreateClosedException(), Guid.Empty, this);
- case CommunicationState.Faulted:
- throw TraceUtility.ThrowHelperError(this.CreateFaultedException(), Guid.Empty, this);
- default:
- throw Fx.AssertAndThrow("ThrowIfClosedOrNotOpen: Unknown CommunicationObject.state");
- }
- }
- internal void ThrowPending()
- {
- ExceptionQueue queue = this.exceptionQueue;
- if (queue != null)
- {
- Exception exception = queue.GetException();
- if (exception != null)
- {
- throw TraceUtility.ThrowHelperError(exception, Guid.Empty, this);
- }
- }
- }
- //
- // State callbacks
- //
- protected abstract void OnAbort();
- protected abstract void OnClose(TimeSpan timeout);
- protected abstract void OnEndClose(IAsyncResult result);
- protected abstract IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state);
- protected abstract void OnOpen(TimeSpan timeout);
- protected abstract IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state);
- protected abstract void OnEndOpen(IAsyncResult result);
- class AlreadyClosedAsyncResult : CompletedAsyncResult
- {
- public AlreadyClosedAsyncResult(AsyncCallback callback, object state)
- : base(callback, state)
- {
- }
- }
- class ExceptionQueue
- {
- Queue<Exception> exceptions = new Queue<Exception>();
- object thisLock;
- internal ExceptionQueue(object thisLock)
- {
- this.thisLock = thisLock;
- }
- object ThisLock
- {
- get { return this.thisLock; }
- }
- public void AddException(Exception exception)
- {
- if (exception == null)
- {
- return;
- }
- lock (this.ThisLock)
- {
- this.exceptions.Enqueue(exception);
- }
- }
- public Exception GetException()
- {
- lock (this.ThisLock)
- {
- if (this.exceptions.Count > 0)
- {
- return this.exceptions.Dequeue();
- }
- }
- return null;
- }
- }
- class OpenAsyncResult : AsyncResult
- {
- static AsyncCompletion onOpenCompletion = new AsyncCompletion(OnOpenCompletion);
- CommunicationObject communicationObject;
- TimeoutHelper timeout;
- public OpenAsyncResult(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.communicationObject = communicationObject;
- this.timeout = new TimeoutHelper(timeout);
- base.OnCompleting = new Action<AsyncResult, Exception>(OnOpenCompleted);
- if (InvokeOpen())
- {
- this.Complete(true);
- }
- }
- bool InvokeOpen()
- {
- IAsyncResult result = this.communicationObject.OnBeginOpen(this.timeout.RemainingTime(),
- base.PrepareAsyncCompletion(onOpenCompletion), this);
- if (result.CompletedSynchronously)
- {
- return OnOpenCompletion(result);
- }
- else
- {
- return false;
- }
- }
- void NotifyOpened()
- {
- this.communicationObject.OnOpened();
- if (!this.communicationObject.onOpenedCalled)
- {
- throw TraceUtility.ThrowHelperError(
- this.communicationObject.CreateBaseClassMethodNotCalledException("OnOpened"),
- Guid.Empty, this.communicationObject);
- }
- }
- void OnOpenCompleted(AsyncResult result, Exception exception)
- {
- if (exception != null)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectOpenFailed,
- SR.GetString(SR.TraceCodeCommunicationObjectOpenFailed, this.communicationObject.GetCommunicationObjectType().ToString()),
- this, exception);
- }
- this.communicationObject.Fault();
- }
- }
- static bool OnOpenCompletion(IAsyncResult result)
- {
- OpenAsyncResult thisPtr = (OpenAsyncResult)result.AsyncState;
- thisPtr.communicationObject.OnEndOpen(result);
- thisPtr.NotifyOpened();
- return true;
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<OpenAsyncResult>(result);
- }
- }
- class CloseAsyncResult : TraceAsyncResult
- {
- static AsyncCompletion onCloseCompletion = new AsyncCompletion(OnCloseCompletion);
- CommunicationObject communicationObject;
- TimeoutHelper timeout;
- public CloseAsyncResult(CommunicationObject communicationObject, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.communicationObject = communicationObject;
- this.timeout = new TimeoutHelper(timeout);
- base.OnCompleting = new Action<AsyncResult, Exception>(OnCloseCompleted);
- if (InvokeClose())
- {
- this.Complete(true);
- }
- }
- bool InvokeClose()
- {
- IAsyncResult result = this.communicationObject.OnBeginClose(this.timeout.RemainingTime(),
- base.PrepareAsyncCompletion(onCloseCompletion), this);
- if (result.CompletedSynchronously)
- {
- return OnCloseCompletion(result);
- }
- else
- {
- return false;
- }
- }
- void NotifyClosed()
- {
- this.communicationObject.OnClosed();
- if (!this.communicationObject.onClosedCalled)
- {
- throw TraceUtility.ThrowHelperError(
- this.communicationObject.CreateBaseClassMethodNotCalledException("OnClosed"),
- Guid.Empty, this.communicationObject);
- }
- }
- void OnCloseCompleted(AsyncResult result, Exception exception)
- {
- if (exception != null)
- {
- if (DiagnosticUtility.ShouldTraceWarning)
- {
- TraceUtility.TraceEvent(TraceEventType.Warning, TraceCode.CommunicationObjectCloseFailed,
- SR.GetString(SR.TraceCodeCommunicationObjectCloseFailed, this.communicationObject.GetCommunicationObjectType().ToString()),
- this, exception);
- }
- this.communicationObject.Abort();
- }
- }
- static bool OnCloseCompletion(IAsyncResult result)
- {
- CloseAsyncResult thisPtr = (CloseAsyncResult)result.AsyncState;
- thisPtr.communicationObject.OnEndClose(result);
- thisPtr.NotifyClosed();
- return true;
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<CloseAsyncResult>(result);
- }
- }
- }
- }
|