| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System;
- using System.Runtime;
- using System.ServiceModel;
- class ContextChannelRequestContext : RequestContext
- {
- ContextProtocol contextProtocol;
- TimeSpan defaultSendTimeout;
- RequestContext innerContext;
- public ContextChannelRequestContext(RequestContext innerContext, ContextProtocol contextProtocol, TimeSpan defaultSendTimeout)
- {
- if (innerContext == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("innerContext");
- }
- if (contextProtocol == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("contextProtocol");
- }
- this.innerContext = innerContext;
- this.contextProtocol = contextProtocol;
- this.defaultSendTimeout = defaultSendTimeout;
- }
- public override Message RequestMessage
- {
- get { return this.innerContext.RequestMessage; }
- }
- public override void Abort()
- {
- this.innerContext.Abort();
- }
- public override IAsyncResult BeginReply(Message message, TimeSpan timeout, AsyncCallback callback, object state)
- {
- return new ReplyAsyncResult(message, this, timeout, callback, state);
- }
- public override IAsyncResult BeginReply(Message message, AsyncCallback callback, object state)
- {
- return this.BeginReply(message, this.defaultSendTimeout, callback, state);
- }
- public override void Close(TimeSpan timeout)
- {
- this.innerContext.Close(timeout);
- }
- public override void Close()
- {
- this.innerContext.Close();
- }
- public override void EndReply(IAsyncResult result)
- {
- ReplyAsyncResult.End(result);
- }
- public override void Reply(Message message, TimeSpan timeout)
- {
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- Message replyMessage = message;
- if (message != null)
- {
- this.contextProtocol.OnOutgoingMessage(message, this);
- CorrelationCallbackMessageProperty callback;
- if (CorrelationCallbackMessageProperty.TryGet(message, out callback))
- {
- ContextExchangeCorrelationHelper.AddOutgoingCorrelationCallbackData(callback, message, false);
- if (callback.IsFullyDefined)
- {
- replyMessage = callback.FinalizeCorrelation(message, timeoutHelper.RemainingTime());
- // we are done finalizing correlation, removing the messageproperty since we do not need it anymore
- replyMessage.Properties.Remove(CorrelationCallbackMessageProperty.Name);
- }
- }
- }
- try
- {
- this.innerContext.Reply(replyMessage, timeoutHelper.RemainingTime());
- }
- finally
- {
- if (message != null && !object.ReferenceEquals(message, replyMessage))
- {
- replyMessage.Close();
- }
- }
- }
- public override void Reply(Message message)
- {
- this.Reply(message, this.defaultSendTimeout);
- }
- class ReplyAsyncResult : AsyncResult
- {
- static AsyncCallback onFinalizeCorrelation = Fx.ThunkCallback(new AsyncCallback(OnFinalizeCorrelationCompletedCallback));
- static AsyncCallback onReply = Fx.ThunkCallback(new AsyncCallback(OnReplyCompletedCallback));
- ContextChannelRequestContext context;
- CorrelationCallbackMessageProperty correlationCallback;
- Message message;
- Message replyMessage;
- TimeoutHelper timeoutHelper;
- public ReplyAsyncResult(Message message, ContextChannelRequestContext context, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.context = context;
- this.message = this.replyMessage = message;
- this.timeoutHelper = new TimeoutHelper(timeout);
- bool shouldReply = true;
- if (message != null)
- {
- this.context.contextProtocol.OnOutgoingMessage(message, this.context);
- if (CorrelationCallbackMessageProperty.TryGet(message, out this.correlationCallback))
- {
- ContextExchangeCorrelationHelper.AddOutgoingCorrelationCallbackData(this.correlationCallback, message, false);
- if (this.correlationCallback.IsFullyDefined)
- {
- IAsyncResult result = correlationCallback.BeginFinalizeCorrelation(this.message, this.timeoutHelper.RemainingTime(), onFinalizeCorrelation, this);
- if (result.CompletedSynchronously)
- {
- if (OnFinalizeCorrelationCompleted(result))
- {
- base.Complete(true);
- }
- }
- shouldReply = false;
- }
- }
- }
- if (shouldReply)
- {
- IAsyncResult result = this.context.innerContext.BeginReply(this.message, this.timeoutHelper.RemainingTime(), onReply, this);
- if (result.CompletedSynchronously)
- {
- OnReplyCompleted(result);
- base.Complete(true);
- }
- }
- }
- public static void End(IAsyncResult result)
- {
- AsyncResult.End<ReplyAsyncResult>(result);
- }
- static void OnFinalizeCorrelationCompletedCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- ReplyAsyncResult thisPtr = (ReplyAsyncResult)result.AsyncState;
- Exception completionException = null;
- bool completeSelf;
- try
- {
- completeSelf = thisPtr.OnFinalizeCorrelationCompleted(result);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- completeSelf = true;
- }
- if (completeSelf)
- {
- thisPtr.Complete(false, completionException);
- }
- }
- static void OnReplyCompletedCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- ReplyAsyncResult thisPtr = (ReplyAsyncResult)result.AsyncState;
- Exception completionException = null;
- try
- {
- thisPtr.OnReplyCompleted(result);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- thisPtr.Complete(false, completionException);
- }
- bool OnFinalizeCorrelationCompleted(IAsyncResult result)
- {
- this.replyMessage = this.correlationCallback.EndFinalizeCorrelation(result);
- bool throwing = true;
- IAsyncResult replyResult;
- try
- {
- replyResult = this.context.innerContext.BeginReply(this.replyMessage, this.timeoutHelper.RemainingTime(), onReply, this);
- throwing = false;
- }
- finally
- {
- if (throwing)
- {
- if (this.message != null && !object.ReferenceEquals(this.message, this.replyMessage))
- {
- this.replyMessage.Close();
- }
- }
- }
- if (replyResult.CompletedSynchronously)
- {
- OnReplyCompleted(replyResult);
- return true;
- }
- return false;
- }
- void OnReplyCompleted(IAsyncResult result)
- {
- try
- {
- this.context.innerContext.EndReply(result);
- }
- finally
- {
- if (this.message != null && !object.ReferenceEquals(this.message, this.replyMessage))
- {
- this.replyMessage.Close();
- }
- }
- }
- }
- }
- }
|