| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Channels
- {
- using System;
- using System.Runtime;
- using System.ServiceModel;
- abstract class ContextRequestChannelBase<TChannel> : LayeredChannel<TChannel> where TChannel : class, IRequestChannel
- {
- ContextProtocol contextProtocol;
- protected ContextRequestChannelBase(ChannelManagerBase channelManager, TChannel innerChannel,
- ContextExchangeMechanism contextExchangeMechanism, Uri callbackAddress, bool contextManagementEnabled)
- : base(channelManager, innerChannel)
- {
- this.contextProtocol = new ClientContextProtocol(contextExchangeMechanism, innerChannel.Via, this, callbackAddress, contextManagementEnabled);
- }
- public EndpointAddress RemoteAddress
- {
- get { return this.InnerChannel.RemoteAddress; }
- }
- public Uri Via
- {
- get { return this.InnerChannel.Via; }
- }
- public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
- {
- this.contextProtocol.OnOutgoingMessage(message, null);
- return new RequestAsyncResult(message, this.InnerChannel, timeout, callback, state);
- }
- public IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state)
- {
- return this.BeginRequest(message, this.DefaultSendTimeout, callback, state);
- }
- public Message EndRequest(IAsyncResult result)
- {
- Message message = RequestAsyncResult.End(result);
- if (message != null)
- {
- this.contextProtocol.OnIncomingMessage(message);
- }
- return message;
- }
- public override T GetProperty<T>()
- {
- if (typeof(T) == typeof(IContextManager) && this.contextProtocol is IContextManager)
- {
- return (T)(object)this.contextProtocol;
- }
- else
- {
- return base.GetProperty<T>();
- }
- }
- public Message Request(Message message, TimeSpan timeout)
- {
- CorrelationCallbackMessageProperty callback = null;
- TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
- Message requestMessage = message;
- this.contextProtocol.OnOutgoingMessage(message, null);
- if (message != null && CorrelationCallbackMessageProperty.TryGet(message, out callback))
- {
- ContextExchangeCorrelationHelper.AddOutgoingCorrelationCallbackData(callback, message, true);
- if (callback.IsFullyDefined)
- {
- requestMessage = callback.FinalizeCorrelation(message, timeoutHelper.RemainingTime());
- }
- }
- Message response = null;
- try
- {
- response = this.InnerChannel.Request(requestMessage, timeout);
- if (response != null)
- {
- this.contextProtocol.OnIncomingMessage(response);
- }
- }
- finally
- {
- if (message != null && !object.ReferenceEquals(message, requestMessage))
- {
- requestMessage.Close();
- }
- }
- return response;
- }
- public Message Request(Message message)
- {
- return this.Request(message, this.DefaultSendTimeout);
- }
- class RequestAsyncResult : AsyncResult
- {
- static AsyncCallback onFinalizeCorrelation = Fx.ThunkCallback(new AsyncCallback(OnFinalizeCorrelationCompletedCallback));
- static AsyncCallback onRequest = Fx.ThunkCallback(new AsyncCallback(OnRequestCompletedCallback));
- IRequestChannel channel;
- CorrelationCallbackMessageProperty correlationCallback;
- Message message;
- Message replyMessage;
- Message requestMessage;
- TimeoutHelper timeoutHelper;
- public RequestAsyncResult(Message message, IRequestChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
- : base(callback, state)
- {
- this.channel = channel;
- this.message = this.requestMessage = message;
- this.timeoutHelper = new TimeoutHelper(timeout);
- bool shouldRequest = true;
- if (message != null)
- {
- if (CorrelationCallbackMessageProperty.TryGet(message, out this.correlationCallback))
- {
- ContextExchangeCorrelationHelper.AddOutgoingCorrelationCallbackData(this.correlationCallback, message, true);
- if (this.correlationCallback.IsFullyDefined)
- {
- IAsyncResult result = this.correlationCallback.BeginFinalizeCorrelation(this.message, this.timeoutHelper.RemainingTime(), onFinalizeCorrelation, this);
- if (result.CompletedSynchronously)
- {
- if (OnFinalizeCorrelationCompleted(result))
- {
- base.Complete(true);
- }
- }
- shouldRequest = false;
- }
- }
- }
- if (shouldRequest)
- {
- IAsyncResult result = this.channel.BeginRequest(this.message, this.timeoutHelper.RemainingTime(), onRequest, this);
- if (result.CompletedSynchronously)
- {
- OnRequestCompleted(result);
- base.Complete(true);
- }
- }
- }
- public static Message End(IAsyncResult result)
- {
- RequestAsyncResult thisPtr = AsyncResult.End<RequestAsyncResult>(result);
- return thisPtr.replyMessage;
- }
- static void OnFinalizeCorrelationCompletedCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- RequestAsyncResult thisPtr = (RequestAsyncResult)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 OnRequestCompletedCallback(IAsyncResult result)
- {
- if (result.CompletedSynchronously)
- {
- return;
- }
- RequestAsyncResult thisPtr = (RequestAsyncResult)result.AsyncState;
- Exception completionException = null;
- try
- {
- thisPtr.OnRequestCompleted(result);
- }
- catch (Exception e)
- {
- if (Fx.IsFatal(e))
- {
- throw;
- }
- completionException = e;
- }
- thisPtr.Complete(false, completionException);
- }
- bool OnFinalizeCorrelationCompleted(IAsyncResult result)
- {
- this.requestMessage = this.correlationCallback.EndFinalizeCorrelation(result);
- this.requestMessage.Properties.Remove(CorrelationCallbackMessageProperty.Name);
- bool throwing = true;
- IAsyncResult requestResult;
- try
- {
- requestResult = this.channel.BeginRequest(this.requestMessage, this.timeoutHelper.RemainingTime(), onRequest, this);
- throwing = false;
- }
- finally
- {
- if (throwing)
- {
- if (this.message != null && !object.ReferenceEquals(this.message, this.requestMessage))
- {
- this.requestMessage.Close();
- }
- }
- }
- if (requestResult.CompletedSynchronously)
- {
- OnRequestCompleted(requestResult);
- return true;
- }
- return false;
- }
- void OnRequestCompleted(IAsyncResult result)
- {
- try
- {
- this.replyMessage = this.channel.EndRequest(result);
- }
- finally
- {
- if (this.message != null && !object.ReferenceEquals(this.message, this.requestMessage))
- {
- this.requestMessage.Close();
- }
- }
- }
- }
- }
- }
|