private void SendCallback(IAsyncResult result)
        {
            AsyncDuplexRequest asyncState = result.AsyncState as AsyncDuplexRequest;

            if (!result.CompletedSynchronously)
            {
                asyncState.FinishedSend(result, false);
            }
        }
        public Message EndRequest(IAsyncResult result)
        {
            AsyncDuplexRequest request = result as AsyncDuplexRequest;

            if (request == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentException(System.ServiceModel.SR.GetString("InvalidAsyncResult")));
            }
            return(request.End());
        }
Beispiel #3
0
        public async Task <Message> RequestAsync(Message message, CancellationToken token)
        {
            RequestReplyCorrelator.PrepareRequest(message);
            AsyncDuplexRequest duplexRequest = new AsyncDuplexRequest(this);

            lock (ThisLock)
            {
                RequestStarting(message, duplexRequest);
            }

            await _channel.SendAsync(message, token);

            return(await duplexRequest.WaitForReplyAsync(token));
        }
        public IAsyncResult BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
        {
            IAsyncResult       result2;
            bool               flag    = false;
            AsyncDuplexRequest request = null;

            try
            {
                RequestReplyCorrelator.PrepareRequest(message);
                request = new AsyncDuplexRequest(message, this, timeout, callback, state);
                lock (this.ThisLock)
                {
                    this.RequestStarting(message, request);
                }
                IAsyncResult sendResult = this.channel.BeginSend(message, timeout, Fx.ThunkCallback(new AsyncCallback(this.SendCallback)), request);
                if (sendResult.CompletedSynchronously)
                {
                    request.FinishedSend(sendResult, true);
                }
                this.EnsurePumping();
                flag    = true;
                result2 = request;
            }
            finally
            {
                lock (this.ThisLock)
                {
                    if (flag)
                    {
                        request.EnableCompletion();
                    }
                    else
                    {
                        this.RequestCompleting(request);
                    }
                }
            }
            return(result2);
        }
        public async Task <Message> RequestAsync(Message message, CancellationToken token)
        {
            AsyncDuplexRequest duplexRequest = null;
            bool optimized = false;

            RequestReplyCorrelator.PrepareRequest(message);

            lock (ThisLock)
            {
                if (!Pumping)
                {
                    optimized       = true;
                    syncPumpEnabled = true;
                }

                if (!optimized)
                {
                    duplexRequest = new AsyncDuplexRequest(this);
                }

                RequestStarting(message, duplexRequest);
            }

            if (optimized)
            {
                UniqueId messageId = message.Headers.MessageId;

                try
                {
                    await channel.SendAsync(message, token);

                    //if (DiagnosticUtility.ShouldUseActivity &&
                    //    ServiceModelActivity.Current != null &&
                    //    ServiceModelActivity.Current.ActivityType == ActivityType.ProcessAction)
                    //{
                    //    ServiceModelActivity.Current.Suspend();
                    //}

                    for (;;)
                    {
                        var result = await channel.TryReceiveAsync(token);

                        if (!result.Success)
                        {
                            // TODO: Derive CancellationToken to attach timeout
                            throw TraceUtility.ThrowHelperError(GetReceiveTimeoutException(TimeSpan.Zero), message);
                        }

                        if (result.Result == null)
                        {
                            AbortRequests();
                            return(null);
                        }

                        if (result.Result.Headers.RelatesTo == messageId)
                        {
                            ThrowIfInvalidReplyIdentity(result.Result);
                            return(result.Result);
                        }
                        else if (!HandleRequestAsReply(result.Result))
                        {
                            // SFx drops a message here
                            //if (DiagnosticUtility.ShouldTraceInformation)
                            //{
                            //    EndpointDispatcher dispatcher = null;
                            //    if (this.ChannelHandler != null && this.ChannelHandler.Channel != null)
                            //    {
                            //        dispatcher = this.ChannelHandler.Channel.EndpointDispatcher;
                            //    }
                            //    TraceUtility.TraceDroppedMessage(reply, dispatcher);
                            //}
                            result.Result.Close();
                        }
                    }
                }
                finally
                {
                    lock (ThisLock)
                    {
                        RequestCompleting(null);
                        syncPumpEnabled = false;
                        if (pending > 0)
                        {
                            EnsurePumping();
                        }
                    }
                }
            }
            else
            {
                await channel.SendAsync(message, token);

                EnsurePumping();
                return(await duplexRequest.WaitForReplyAsync(token));
            }
        }