/// <summary> /// Terminates all pending operations with the exception passed. /// </summary> /// <param name="e">The termination exception.</param> protected override void TerminatePendingOperations(Exception e) { using (TimedLock.Lock(this)) { // Send CancelExceptions back to the client for all queued requests. while (requestQueue.Count > 0) { requestQueue.Dequeue().Context.Cancel(); } // Send CancelExceptions back to the client for all requests // already being processed by this channel. if (pendingRequests != null) { foreach (MsgRequestContext requestInfo in pendingRequests.Values) { requestInfo.Cancel(); } pendingRequests.Clear(); } } }
/// <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 receive a message (using the specified timeout). /// </summary> /// <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(TimeSpan,AsyncCallback,object)" /> must eventually be followed by a call to <see cref="EndReceive" />. /// </note> /// </remarks> public IAsyncResult BeginReceive(TimeSpan timeout, AsyncCallback callback, object state) { using (TimedLock.Lock(this)) { // Non-open channels always return null. if (base.State != CommunicationState.Opened) { AsyncResult <Message, InputChannel> arReceive; // Note that TInternal==InputChannel. This is used below in EndReceive() // to distinguish between IAsyncResults returned by this class and those // returned by the listener. arReceive = new AsyncResult <Message, InputChannel>(null, callback, state); arReceive.Result = null; arReceive.Started(ServiceModelHelper.AsyncTrace); arReceive.Notify(); return(arReceive); } // If the channel already has a message queued, then setup to return it. if (msgQueue.Count > 0) { AsyncResult <Message, InputChannel> arReceive; // Note that TInternal==InputChannel. This is used below in EndReceive() // to distinguish between IAsyncResults returned by this class and those // returned by the listener. arReceive = new AsyncResult <Message, InputChannel>(null, callback, state); arReceive.Result = msgQueue.Dequeue(); arReceive.Started(ServiceModelHelper.AsyncTrace); arReceive.Notify(); return(arReceive); } } return(listener.BeginReceive(this, timeout, callback, state)); }
private void Cleanup(Exception e) { using (TimedLock.Lock(ChannelHost.SyncRoot)) { if (hostStarted) { // Remove the route from the message router. if (ChannelHost.Router != null) { ChannelHost.Router.Dispatcher.RemoveTarget(this); } hostStarted = false; ChannelHost.Stop(); } } List <LillTekChannelBase> abortChannels = null; using (TimedLock.Lock(this)) { // Terminate any pending accepts if (acceptQueue != null) { while (acceptQueue.Count > 0) { acceptQueue.Dequeue().Notify(); } acceptQueue = null; } // Terminate any pending waits if (waitQueue != null) { while (waitQueue.Count > 0) { waitQueue.Dequeue().Notify(); } waitQueue = null; } // Abort any queued accepted channels if (channelQueue != null) { while (channelQueue.Count > 0) { TInternal channel = channelQueue.Dequeue(); if (channel.State != CommunicationState.Closed) { channel.Abort(); } } channelQueue = null; } // $todo(jeff.lill): Delete this ------------------------ // Setup to abort all of the listener's channels. if (channels != null && channels.Count > 0) { abortChannels = new List <LillTekChannelBase>(channels.Count); foreach (LillTekChannelBase channel in channels.Values) { abortChannels.Add(channel); } } //--------------------------------------------------- // Stop the background task timer onBkTask = null; } // Actually abort the channels outside of the lock. if (abortChannels != null) { foreach (LillTekChannelBase channel in abortChannels) { channel.Close(); } } }