/// <summary> /// Begins an asynchronous operation to receive a channel request (using a specified timeout). /// </summary> /// <param name="channel">The channel.</param> /// <param name="timeout">The <see cref="TimeSpan" /> value specifying the maximum time to wait for a request.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// <note> /// All calls to <see cref="BeginReceiveRequest" /> must eventually be followed by a call to <see cref="EndReceiveRequest" />. /// </note> /// </remarks> public IAsyncResult BeginReceiveRequest(ReplyChannel channel, TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult <RequestInfo, ReplyChannel> arReceive; using (TimedLock.Lock(this)) { timeout = ServiceModelHelper.ValidateTimeout(timeout); arReceive = new AsyncResult <RequestInfo, ReplyChannel>(null, callback, state); arReceive.TTD = SysTime.Now + timeout; arReceive.InternalState = channel; arReceive.Started(ServiceModelHelper.AsyncTrace); // Check to see if we already have a queued request. if (requestQueue.Count > 0) { arReceive.Result = requestQueue.Dequeue(); arReceive.Notify(); return(arReceive); } // Otherwise queue the receive operation. receiveQueue.Enqueue(arReceive); return(arReceive); } }
/// <summary> /// Initiates an asynchronous request/response transmission with a specific timeout. /// </summary> /// <param name="message">The request message.</param> /// <param name="timeout">The maximum time to wait for a response.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">The application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// <note> /// All successful calls to <see cref="BeginRequest(Message,TimeSpan,AsyncCallback,object)" /> must /// eventually be followed by a call to <see cref="EndRequest" />. /// </note> /// </remarks> public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state) { using (TimedLock.Lock(this)) { ThrowIfDisposedOrNotOpen(); ServiceModelHelper.ValidateTimeout(timeout); try { using (MemoryStream ms = new MemoryStream(payloadEstimator.EstimateNextBufferSize())) { WcfEnvelopeMsg requestMsg = new WcfEnvelopeMsg(); encoder.WriteMessage(message, ms); payloadEstimator.LastPayloadSize((int)ms.Length); requestMsg.Payload = new ArraySegment <byte>(ms.GetBuffer(), 0, (int)ms.Length); return(ChannelHost.Router.BeginQuery(ep, requestMsg, callback, state)); } } catch (Exception e) { throw ServiceModelHelper.GetCommunicationException(e); } } }
/// <summary> /// Internal event handler. /// </summary> /// <param name="timeout"></param> /// <returns></returns> protected override TChannel OnAcceptChannel(TimeSpan timeout) { IAsyncResult arAccept; timeout = ServiceModelHelper.ValidateTimeout(timeout); arAccept = BeginAcceptChannel(timeout, null, null); return(EndAcceptChannel(arAccept)); }
/// <summary> /// Internal event handler. /// </summary> /// <param name="timeout"></param> /// <returns></returns> protected override bool OnWaitForChannel(TimeSpan timeout) { IAsyncResult arWait; timeout = ServiceModelHelper.ValidateTimeout(timeout); arWait = BeginWaitForChannel(timeout, null, null); return(EndWaitForChannel(arWait)); }
/// <summary> /// Synchronously sends a message-based request and then waits for the correlated message-based response, /// using a specific timeout value. /// </summary> /// <param name="message">The request message.</param> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param> /// <returns>The correlated response.</returns> /// <remarks> /// This override will use <paramref name="timeout" /> value passed /// as the maximum time to wait for a response. /// </remarks> public Message Request(Message message, TimeSpan timeout) { IAsyncResult arRequest; ServiceModelHelper.ValidateTimeout(timeout); arRequest = BeginRequest(message, timeout, null, null); return(EndRequest(arRequest)); }
/// <summary> /// Inserts processing on a communication object after it transitions to the opening /// state due to the invocation of an asynchronous open operation. /// </summary> /// <param name="timeout">The <see cref="TimeSpan" /> that specifies how long the on open operation has to complete before timing out.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// The base class implementation initiates an asynchronous operation that will /// complete immediately on another thread. /// </remarks> protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { ServiceModelHelper.ValidateTimeout(timeout); session.ReceiveEvent += new DuplexReceiveDelegate(OnSessionReceive); session.QueryEvent += new DuplexQueryDelegate(OnSessionQuery); session.CloseEvent += new DuplexCloseDelegate(OnSessionClose); return(session.BeginConnect(ep, callback, state)); }
/// <summary> /// Inserts processing on a communication object after it transitions to the opening /// state due to the invocation of an asynchronous open operation. /// </summary> /// <param name="timeout">The <see cref="TimeSpan" /> that specifies how long the on open operation has to complete before timing out.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// The base class implementation initiates an asynchronous operation that will /// complete immediately on another thread. /// </remarks> protected override IAsyncResult OnBeginOpen(TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult arOpen; ServiceModelHelper.ValidateTimeout(timeout); arOpen = new AsyncResult(null, callback, state); arOpen.Started(ServiceModelHelper.AsyncTrace); arOpen.Notify(); return(arOpen); }
/// <summary> /// Internal event handler. /// </summary> /// <param name="timeout"></param> /// <param name="callback"></param> /// <param name="state"></param> /// <returns></returns> protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult ar; Cleanup(ServiceModelHelper.CreateObjectDisposedException(this)); timeout = ServiceModelHelper.ValidateTimeout(timeout); ar = new AsyncResult(null, callback, state); ar.Started(ServiceModelHelper.AsyncTrace); ar.Notify(); return(ar); }
/// <summary> /// Inserts processing after a communication object transitions to the closing state /// due to the invocation of an asynchronous close operation. /// </summary> /// <param name="timeout">The <see cref="TimeSpan" /> that specifies how long the on close operation has to complete before timing out.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> to be used to track the status of the operation.</returns> /// <remarks> /// The base class implementation initiates an asynchronous operation that will /// complete immediately on another thread. /// </remarks> protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult arClose; ServiceModelHelper.ValidateTimeout(timeout); session.Close(); arClose = new AsyncResult(null, callback, state); arClose.Started(ServiceModelHelper.AsyncTrace); arClose.Notify(); return(arClose); }
/// <summary> /// Initiates an asynchronous attempt to receive a message within the /// specified period of time, where a boolean will ultimately be returned /// indicating success or failure rather than throwning an exception if /// an error is encountered. /// </summary> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait for the message.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// All successful calls to <see cref="BeginTryReceive" /> must eventually be followed by a /// call to <see cref="EndTryReceive" />. /// </remarks> public IAsyncResult BeginTryReceive(TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult <Message, object> arReceive; using (TimedLock.Lock(this)) { timeout = ServiceModelHelper.ValidateTimeout(timeout); arReceive = new AsyncResult <Message, object>(null, callback, state); arReceive.TTD = SysTime.Now + timeout; arReceive.Started(ServiceModelHelper.AsyncTrace); // Non-open channels always return true (message=null) if (base.State != CommunicationState.Opened) { arReceive.Result = null; arReceive.Notify(); return(arReceive); } // Check to see if we already have a queued message. if (msgQueue.Count > 0) { arReceive.Result = msgQueue.Dequeue(); arReceive.Notify(); return(arReceive); } // Setup to return null if the remote side of the connection // has been closed. if (!session.IsConnected) { arReceive.Notify(); return(arReceive); } // Otherwise queue the receive operation. receiveQueue.Enqueue(arReceive); return(arReceive); } }
/// <summary> /// Begins an asynchronous operation to wait for a specified period of time for a message to be received /// or queued internally by the channel. /// </summary> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// All successful calls to <see cref="BeginWaitForMessage" /> must eventually be followed by a call to <see cref="EndWaitForMessage" />. /// </remarks> public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult <bool, object> arWait; using (TimedLock.Lock(this)) { timeout = ServiceModelHelper.ValidateTimeout(timeout); arWait = new AsyncResult <bool, object>(null, callback, state); arWait.TTD = SysTime.Now + timeout; arWait.Started(ServiceModelHelper.AsyncTrace); // Non-open channels always return false if (base.State != CommunicationState.Opened) { arWait.Result = false; arWait.Notify(); return(arWait); } // Check to see if we already have a queued message. if (msgQueue.Count > 0) { arWait.Result = true; arWait.Notify(); return(arWait); } // Setup to return false if the remote side of the session // has been closed. if (!session.IsConnected) { arWait.Notify(); return(arWait); } // Otherwise queue the wait operation. waitQueue.Enqueue(arWait); return(arWait); } }
public void ServiceModelHelper_ValidateTimeout() { TimeSpan timeout; ServiceModelHelper.ValidateTimeout(TimeSpan.Zero); ServiceModelHelper.ValidateTimeout(TimeSpan.FromMinutes(100)); try { ServiceModelHelper.ValidateTimeout(TimeSpan.FromMinutes(-100)); Assert.Fail("Expected an ArgumentException"); } catch (ArgumentException) { } timeout = ServiceModelHelper.ValidateTimeout(TimeSpan.MaxValue); Assert.IsTrue(SysTime.Now + timeout < DateTime.MaxValue); }
/// <summary> /// Begins an asynchronous operation to wait for a specified period of time for a message to be received /// for a channel. /// </summary> /// <param name="channel">The channel.</param> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// All successful calls to <see cref="BeginWaitForMessage" /> must eventually be followed by a call to <see cref="EndWaitForMessage" />. /// </remarks> public IAsyncResult BeginWaitForMessage(InputChannel channel, TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult <bool, InputChannel> arWait; using (TimedLock.Lock(this)) { timeout = ServiceModelHelper.ValidateTimeout(timeout); arWait = new AsyncResult <bool, InputChannel>(null, callback, state); arWait.TTD = SysTime.Now + timeout; arWait.InternalState = channel; arWait.Started(ServiceModelHelper.AsyncTrace); // Non-open channels always return false. if (base.State != CommunicationState.Opened) { arWait.Notify(); return(arWait); } // If we already have a queued message, dequeue it and add it to the // channel's message queue, so a subsequent call Receive() on the channel // will be assured to succeed. Then notify that the operation is complete. if (msgQueue.Count > 0) { channel.Enqueue(msgQueue.Dequeue()); arWait.Result = true; arWait.Notify(); return(arWait); } // Otherwise queue the wait operation. waitQueue.Enqueue(arWait); return(arWait); } }
/// <summary> /// Begins an asynchronous operation to wait for a specified period of time for a message to be received /// or queued internally by the channel. /// </summary> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// All successful calls to <see cref="BeginWaitForMessage" /> must eventually be followed by a call to <see cref="EndWaitForMessage" />. /// </remarks> public IAsyncResult BeginWaitForMessage(TimeSpan timeout, AsyncCallback callback, object state) { using (TimedLock.Lock(this)) { // Non-open channels always return false. if (base.State != CommunicationState.Opened) { AsyncResult <bool, InputChannel> arWait; // Note that TInternal==InputChannel. This is used below in EndWaitForMessage() // to distinguish between IAsyncResults returned by this class and those // returned by the listener. arWait = new AsyncResult <bool, InputChannel>(null, callback, state); arWait.Result = false; arWait.Started(ServiceModelHelper.AsyncTrace); arWait.Notify(); return(arWait); } // If the channel already has a message queued, then setup to return it. if (msgQueue.Count > 0) { AsyncResult <bool, InputChannel> arWait; // Note that TInternal==InputChannel. This is used below in EndWaitForMessage() // to distinguish between IAsyncResults returned by this class and those // returned by the listener. arWait = new AsyncResult <bool, InputChannel>(null, callback, state); arWait.Result = true; arWait.Started(ServiceModelHelper.AsyncTrace); arWait.Notify(); return(arWait); } } timeout = ServiceModelHelper.ValidateTimeout(timeout); return(listener.BeginWaitForMessage(this, timeout, callback, state)); }
/// <summary> /// Internal event handler. /// </summary> /// <param name="timeout"></param> /// <param name="callback"></param> /// <param name="state"></param> /// <returns></returns> protected override IAsyncResult OnBeginWaitForChannel(TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult <bool, object> arWait; arWait = new AsyncResult <bool, object>(null, callback, state); arWait.TTD = SysTime.Now + ServiceModelHelper.ValidateTimeout(timeout); arWait.Started(ServiceModelHelper.AsyncTrace); using (TimedLock.Lock(this)) { if (channelQueue.Count > 0) { arWait.Result = true; arWait.Notify(); } else { // Give the derived class a chance to accept a channel TInternal acceptChannel; acceptChannel = GetAcceptChannel(); if (acceptChannel != null) { channelQueue.Enqueue(acceptChannel); arWait.Result = true; arWait.Notify(); } else { waitQueue.Enqueue(arWait); } } } return(arWait); }
/// <summary> /// Begins an asynchronous operation to receive a channel message (using a specified timeout). /// </summary> /// <param name="channel">The channel.</param> /// <param name="timeout">The <see cref="TimeSpan" /> value specifying the maximum time to wait for a message.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// <note> /// All calls to <see cref="BeginReceive" /> must eventually be followed by a call to <see cref="EndReceive" />. /// </note> /// </remarks> public IAsyncResult BeginReceive(InputChannel channel, TimeSpan timeout, AsyncCallback callback, object state) { AsyncResult <Message, InputChannel> arReceive; using (TimedLock.Lock(this)) { timeout = ServiceModelHelper.ValidateTimeout(timeout); arReceive = new AsyncResult <Message, InputChannel>(null, callback, state); arReceive.TTD = SysTime.Now + timeout; arReceive.InternalState = channel; arReceive.Started(ServiceModelHelper.AsyncTrace); // Non-open channels always return null. if (base.State != CommunicationState.Opened) { arReceive.Result = null; arReceive.Notify(); return(arReceive); } // Check to see if we already have a queued message. if (msgQueue.Count > 0) { arReceive.Result = msgQueue.Dequeue(); arReceive.Notify(); return(arReceive); } // Otherwise queue the receive operation. receiveQueue.Enqueue(arReceive); return(arReceive); } }
/// <summary> /// Initiates an asynchronous operation to send a message on the output channel, waiting a /// maximum amount of time for the message to be sent. /// </summary> /// <param name="message">The <see cref="Message" />.</param> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param> /// <param name="callback">The <see cref="AsyncCallback" /> delegate to be called when the operation completes (or <c>null</c>).</param> /// <param name="state">Application specific state (or <c>null</c>).</param> /// <returns>The <see cref="IAsyncResult" /> instance to be used to track the status of the operation.</returns> /// <remarks> /// <note> /// This method does not guarantee delivery of the message. /// Messages can be silently dropped for reasons including lack of buffer /// space, network congestion, unavailable remote endpoint, etc. /// </note> /// <note> /// All successful calls to <see cref="BeginSend(Message,TimeSpan,AsyncCallback,object)" /> must eventually be followed by a /// call to <see cref="EndSend" />. /// </note> /// </remarks> public IAsyncResult BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state) { ServiceModelHelper.ValidateTimeout(timeout); return(BeginSend(message, callback, state)); }
/// <summary> /// Synchronously sends a message on the output channel, waiting a /// maximum amount of time for the message to be sent. /// </summary> /// <param name="message">The <see cref="Message" />.</param> /// <param name="timeout">The maximum <see cref="TimeSpan" /> to wait.</param> /// <remarks> /// <note> /// This method does not guarantee delivery of the message. /// Messages can be silently dropped for reasons including lack of buffer /// space, network congestion, unavailable remote endpoint, etc. /// </note> /// </remarks> public void Send(Message message, TimeSpan timeout) { ServiceModelHelper.ValidateTimeout(timeout); Send(message); }