Пример #1
0
        public Task AsynchronousInvoke(
            IRequestChannel channel,
            TChannelBufferInputTransport inputTransport,
            TChannelBufferOutputTransport outputTransport,
            TProtocol inputProtocol,
            TProtocol outputProtocol,
            int sequenceId,
            ClientContextChain contextChain,
            Object[] args)
        {
            //Mark: 微软没有提供 TaskCompletionSource 的非泛型类型,只能使用动态类型处理。
            TaskCompletionSourceEx future;

            if (_successCodec.Type != ThriftType.Void)
            {
                future = new TaskCompletionSourceEx(_successCodec.Type.CSharpType);
            }
            else
            {
                future = new TaskCompletionSourceEx(typeof(Object));
            }
            var requestContext = RequestContexts.GetCurrentContext();

            contextChain.PreWrite(args);
            outputTransport.ResetOutputBuffer();
            WriteArguments(outputProtocol, sequenceId, args);
            IByteBuffer requestBuffer = outputTransport.OutputBuffer.Copy();

            contextChain.PostWrite(args);

            requestBuffer.Retain();
            channel.SendAsynchronousRequest(requestBuffer, false,
                                            new RequestListener(
                                                onRequestSent: reqs =>
            {
                reqs.Release();
                if (this._oneway)
                {
                    try
                    {
                        ForceDoneChain(contextChain);
                        future.TrySetResult(null);
                    }
                    catch (Exception e)
                    {
                        ForceDoneChain(contextChain);
                        future.TrySetException(e);
                    }
                }
            },
                                                onResponseReceive: message =>
            {
                IRequestContext oldRequestContext = RequestContexts.GetCurrentContext();
                RequestContexts.SetCurrentContext(requestContext);
                try
                {
                    contextChain.PreRead();
                    inputTransport.SetInputBuffer(message);
                    WaitForResponse(inputProtocol, sequenceId);
                    Object results = ReadResponse(inputProtocol);
                    contextChain.PostRead(results);
                    ForceDoneChain(contextChain);
                    future.TrySetResult(results);
                }
                catch (Exception e)
                {
                    var wrapException = ThriftClientManager.WrapTException(e);
                    contextChain.PostReadException(e);
                    ForceDoneChain(contextChain);
                    future.TrySetException(wrapException);
                }
                finally
                {
                    RequestContexts.SetCurrentContext(oldRequestContext);
                }
            },
                                                onChannelError: e =>
            {
                if (requestBuffer.ReferenceCount > 0)
                {
                    requestBuffer.Release();
                }

                IRequestContext oldRequestContext = RequestContexts.GetCurrentContext();
                RequestContexts.SetCurrentContext(requestContext);
                try
                {
                    contextChain.PreReadException(e);
                    ForceDoneChain(contextChain);

                    var wrappedException = ThriftClientManager.WrapTException(e);
                    future.TrySetException(wrappedException);
                }
                finally
                {
                    RequestContexts.SetCurrentContext(oldRequestContext);
                }
            }
                                                ));
            return(future.Task);
        }
Пример #2
0
        private Object SynchronousInvoke(
            IRequestChannel channel,
            TChannelBufferInputTransport inputTransport,
            TChannelBufferOutputTransport outputTransport,
            TProtocol inputProtocol,
            TProtocol outputProtocol,
            int sequenceId,
            ClientContextChain contextChain,
            Object[] args)
        {
            Object results = null;

            // write request
            contextChain.PreWrite(args);
            outputTransport.ResetOutputBuffer();
            WriteArguments(outputProtocol, sequenceId, args);
            // Don't need to copy the output buffer for sync case

            IByteBuffer requestBuffer = outputTransport.OutputBuffer;

            contextChain.PostWrite(args);

            if (!this._oneway)
            {
                IByteBuffer responseBuffer;
                try
                {
                    responseBuffer = SyncClientHelpers.SendSynchronousTwoWayMessage(channel, requestBuffer);
                }
                catch (Exception e)
                {
                    contextChain.PreReadException(e);
                    throw;
                }
                finally
                {
                    requestBuffer.Release();
                }

                // read results
                contextChain.PreRead();
                try
                {
                    inputTransport.SetInputBuffer(responseBuffer);
                    WaitForResponse(inputProtocol, sequenceId);
                    results = ReadResponse(inputProtocol);
                    contextChain.PostRead(results);
                }
                catch (Exception e)
                {
                    contextChain.PostReadException(e);
                    throw;
                }
            }
            else
            {
                try
                {
                    SyncClientHelpers.SendSynchronousOneWayMessage(channel, requestBuffer);
                }
                catch (Exception)
                {
                    throw;
                }
            }

            return(results);
        }