Exemplo n.º 1
0
        /// <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();
                }
            }
        }
Exemplo n.º 2
0
        /// <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);
            }
        }
Exemplo n.º 3
0
        /// <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));
        }
Exemplo n.º 4
0
        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();
                }
            }
        }