1 //------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //------------------------------------------------------------
5 namespace System.ServiceModel.Channels
7 using System.Collections.Generic;
9 using System.ServiceModel;
11 class ReplyChannel : InputQueueChannel<RequestContext>, IReplyChannel
13 EndpointAddress localAddress;
15 public ReplyChannel(ChannelManagerBase channelManager, EndpointAddress localAddress)
16 : base(channelManager)
18 this.localAddress = localAddress;
21 public EndpointAddress LocalAddress
23 get { return localAddress; }
26 public override T GetProperty<T>()
28 if (typeof(T) == typeof(IReplyChannel))
30 return (T)(object)this;
33 T baseProperty = base.GetProperty<T>();
34 if (baseProperty != null)
42 protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
44 return new CompletedAsyncResult(callback, state);
47 protected override void OnEndOpen(IAsyncResult result)
49 CompletedAsyncResult.End(result);
52 protected override void OnOpen(TimeSpan timeout)
56 #region static Helpers to convert TryReceiveRequest to ReceiveRequest
57 internal static RequestContext HelpReceiveRequest(IReplyChannel channel, TimeSpan timeout)
59 RequestContext requestContext;
60 if (channel.TryReceiveRequest(timeout, out requestContext))
62 return requestContext;
66 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
67 ReplyChannel.CreateReceiveRequestTimedOutException(channel, timeout));
71 internal static IAsyncResult HelpBeginReceiveRequest(IReplyChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
73 return new HelpReceiveRequestAsyncResult(channel, timeout, callback, state);
76 internal static RequestContext HelpEndReceiveRequest(IAsyncResult result)
78 return HelpReceiveRequestAsyncResult.End(result);
81 class HelpReceiveRequestAsyncResult : AsyncResult
83 IReplyChannel channel;
85 static AsyncCallback onReceiveRequest = Fx.ThunkCallback(new AsyncCallback(OnReceiveRequest));
86 RequestContext requestContext;
88 public HelpReceiveRequestAsyncResult(IReplyChannel channel, TimeSpan timeout, AsyncCallback callback, object state)
89 : base(callback, state)
91 this.channel = channel;
92 this.timeout = timeout;
93 IAsyncResult result = channel.BeginTryReceiveRequest(timeout, onReceiveRequest, this);
95 if (!result.CompletedSynchronously)
100 HandleReceiveRequestComplete(result);
104 public static RequestContext End(IAsyncResult result)
106 HelpReceiveRequestAsyncResult thisPtr = AsyncResult.End<HelpReceiveRequestAsyncResult>(result);
107 return thisPtr.requestContext;
110 void HandleReceiveRequestComplete(IAsyncResult result)
112 if (!this.channel.EndTryReceiveRequest(result, out this.requestContext))
114 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
115 ReplyChannel.CreateReceiveRequestTimedOutException(this.channel, this.timeout));
119 static void OnReceiveRequest(IAsyncResult result)
121 if (result.CompletedSynchronously)
126 HelpReceiveRequestAsyncResult thisPtr = (HelpReceiveRequestAsyncResult)result.AsyncState;
127 Exception completionException = null;
130 thisPtr.HandleReceiveRequestComplete(result);
132 #pragma warning suppress 56500 // [....], transferring exception to another thread
140 completionException = e;
143 thisPtr.Complete(false, completionException);
147 static Exception CreateReceiveRequestTimedOutException(IReplyChannel channel, TimeSpan timeout)
149 if (channel.LocalAddress != null)
151 return new TimeoutException(SR.GetString(SR.ReceiveRequestTimedOut, channel.LocalAddress.Uri.AbsoluteUri, timeout));
155 return new TimeoutException(SR.GetString(SR.ReceiveRequestTimedOutNoLocalAddress, timeout));
161 public RequestContext ReceiveRequest()
163 return this.ReceiveRequest(this.DefaultReceiveTimeout);
166 public RequestContext ReceiveRequest(TimeSpan timeout)
168 if (timeout < TimeSpan.Zero)
169 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
170 new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
173 return ReplyChannel.HelpReceiveRequest(this, timeout);
176 public IAsyncResult BeginReceiveRequest(AsyncCallback callback, object state)
178 return this.BeginReceiveRequest(this.DefaultReceiveTimeout, callback, state);
181 public IAsyncResult BeginReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
183 if (timeout < TimeSpan.Zero)
185 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
186 new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
190 return ReplyChannel.HelpBeginReceiveRequest(this, timeout, callback, state);
193 public RequestContext EndReceiveRequest(IAsyncResult result)
195 return ReplyChannel.HelpEndReceiveRequest(result);
198 public bool TryReceiveRequest(TimeSpan timeout, out RequestContext context)
200 if (timeout < TimeSpan.Zero)
201 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
202 new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
205 return base.Dequeue(timeout, out context);
208 public IAsyncResult BeginTryReceiveRequest(TimeSpan timeout, AsyncCallback callback, object state)
210 if (timeout < TimeSpan.Zero)
211 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
212 new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
215 return base.BeginDequeue(timeout, callback, state);
218 public bool EndTryReceiveRequest(IAsyncResult result, out RequestContext context)
220 return base.EndDequeue(result, out context);
223 public bool WaitForRequest(TimeSpan timeout)
225 if (timeout < TimeSpan.Zero)
226 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
227 new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
230 return base.WaitForItem(timeout);
233 public IAsyncResult BeginWaitForRequest(TimeSpan timeout, AsyncCallback callback, object state)
235 if (timeout < TimeSpan.Zero)
236 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
237 new ArgumentOutOfRangeException("timeout", timeout, SR.GetString(SR.SFxTimeoutOutOfRange0)));
240 return base.BeginWaitForItem(timeout, callback, state);
243 public bool EndWaitForRequest(IAsyncResult result)
245 return base.EndWaitForItem(result);