コード例 #1
0
        /// <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);
            }
        }
コード例 #2
0
        /// <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);
                }
            }
        }
コード例 #3
0
        /// <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));
        }
コード例 #4
0
        /// <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));
        }
コード例 #5
0
        /// <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));
        }
コード例 #6
0
        /// <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));
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
        /// <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);
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
            }
        }
コード例 #11
0
        /// <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);
            }
        }
コード例 #12
0
        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);
        }
コード例 #13
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);
            }
        }
コード例 #14
0
        /// <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));
        }
コード例 #15
0
        /// <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);
        }
コード例 #16
0
        /// <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);
            }
        }
コード例 #17
0
 /// <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));
 }
コード例 #18
0
 /// <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);
 }