示例#1
0
        ///<summary>
        ///Sends a single message synchronously, blocking until the send is complete. Does not wait for
        ///a response.
        ///<c>
        ///NOTE: the underlying transport may be non-blocking, in which case the blocking is simulated
        ///by waits instead of using blocking network operations.
        ///</c>
        ///</summary>
        ///<exception cref="Thrift.TException">
        ///if a network or protocol error occurs while serializing or sending the request
        ///</exception>
        public static void SendSynchronousOneWayMessage(this IRequestChannel channel, IByteBuffer request)
        {
            TException exceptionHolder = null;

            request.Retain();
            using (ManualResetEventSlim latch = new ManualResetEventSlim(false))
            {
                channel.SendAsynchronousRequest(request, true, new RequestListener(
                                                    onRequestSent: reqs =>
                {
                    reqs?.Release();
                    latch.Set();
                },
                                                    //onResponseReceive: response =>
                                                    //{
                                                    //    communicatingComplete?.Invoke();
                                                    //    latch.Set();
                                                    //},
                                                    onChannelError: e =>
                {
                    exceptionHolder = e;
                    latch.Set();
                }));


                if (!latch.Wait(TimeSpan.FromMinutes(10)))
                {
                    throw new TException("wait for one-way request sent timeout.");
                }
            }
            if (exceptionHolder != null)
            {
                throw exceptionHolder;
            }
        }
示例#2
0
        ///<summary>
        ///Sends a single message synchronously, and blocks until the responses is received.
        ///</summary>
        ///<remarks>
        ///NOTE: the underlying transport may be non-blocking, in which case the blocking is simulated
        ///by waits instead of using blocking network operations.
        ///</remarks>
        ///<returns>The response, stored in a <see cref="IByteBuffer"/></returns>
        ///<exception cref="Thrift.TException">
        /// if an error occurs while serializing or sending the request or while receiving or de-serializing the response
        /// </exception>
        public static IByteBuffer SendSynchronousTwoWayMessage(this IRequestChannel channel, IByteBuffer request)
        {
            request?.Retain();
            IByteBuffer responseHolder  = null;
            TException  exceptionHolder = null;

            using (ManualResetEventSlim latch = new ManualResetEventSlim(false))
            {
                channel.SendAsynchronousRequest(request, false, new RequestListener(
                                                    onRequestSent: reqs => {
                    reqs?.Release();
                },
                                                    onResponseReceive: response =>
                {
                    responseHolder = response;
                    latch.Set();
                },
                                                    onChannelError: e =>
                {
                    exceptionHolder = e;
                    latch.Set();
                }
                                                    ));

                if (!latch.Wait(TimeSpan.FromMinutes(10)))
                {
                    throw new TException("wait for response/error timeout.");
                }
            }

            if (exceptionHolder != null)
            {
                throw exceptionHolder;
            }

            return(responseHolder);
        }
示例#3
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);
        }