예제 #1
0
        public IAsyncResult BeginAsync(AsyncCallback callback, object state)
        {
            if (_waitHandle != null)
            {
                throw new InvalidOperationException("The asynchronous request was already started.");
            }

            _state = state;
            lock (_completionCallbacks)
                _completionCallbacks.Add(callback);

            WaitOrTimerCallback timerCallback = (s, timeoutExpired) =>
            {
                if (timeoutExpired)
                {
                    lock (_completionCallbacks)
                        _completionCallbacks.Add(asyncResult => _timeoutCallback());

                    Fail(RequestTimeoutException.FromCorrelationId(_requestId));
                }
            };

            _waitHandle = ThreadPool.RegisterWaitForSingleObject(CompleteEvent, timerCallback, state, _timeout, true);

            return(this);
        }
예제 #2
0
        void TimeoutExpired()
        {
            if (_timeoutToken != null)
            {
                _timeoutToken.Dispose();
                _timeoutToken = null;
            }

            var timeoutException = new RequestTimeoutException(_requestId.ToString());

            foreach (var handle in _connections.Values)
            {
                handle.TrySetException(timeoutException);
                handle.Disconnect();
            }

            _requestTask.TrySetException(timeoutException);
        }
예제 #3
0
        void TimeoutExpired()
        {
            if (_timeoutToken != null)
            {
                _timeoutToken.Dispose();
                _timeoutToken = null;
            }

            var timeoutException = new RequestTimeoutException(_requestId.ToString());

            _connections.ForEach(x =>
            {
                x.TrySetException(timeoutException);
                x.Disconnect();
            });

            _requestTask.TrySetException(timeoutException);
        }
예제 #4
0
        void HandleTimeout(Task task)
        {
            try
            {
                if (_timeoutHandler != null)
                {
                    _timeoutHandler.HandleTimeout(_message);
                    _source.TrySetResult(_message);
                }
                else
                {
                    var exception = new RequestTimeoutException(_requestId);
                    _source.TrySetException(exception);
                }

                NotifyHandlersOfTimeout();
            }
            finally
            {
                Cleanup();
            }
        }
예제 #5
0
        public bool Wait()
        {
            bool alreadyCompleted;

            lock (_lock)
                alreadyCompleted = _completed;

            bool result = alreadyCompleted || CompleteEvent.WaitOne(_timeout == TimeSpan.MaxValue ? Int32.MaxValue : (int)_timeout.TotalMilliseconds, true);

            if (!result)
            {
                Fail(RequestTimeoutException.FromCorrelationId(_requestId));
            }

            Close();

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

            return(result);
        }
예제 #6
0
        public override AmazonServiceException UnmarshallException(JsonUnmarshallerContext context, Exception innerException, HttpStatusCode statusCode)
        {
            ErrorResponse errorResponse = JsonErrorResponseUnmarshaller.GetInstance().Unmarshall(context);

            if (errorResponse.Code != null && errorResponse.Code.Equals("ResourceNotFoundException"))
            {
                ResourceNotFoundException ex = new ResourceNotFoundException(errorResponse.Message, innerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, statusCode);

                ex.Type = errorResponse.Metadata["Type"];

                ex.Code = errorResponse.Metadata["Code"];

                return(ex);
            }

            if (errorResponse.Code != null && errorResponse.Code.Equals("MissingParameterValueException"))
            {
                MissingParameterValueException ex = new MissingParameterValueException(errorResponse.Message, innerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, statusCode);

                ex.Type = errorResponse.Metadata["Type"];

                ex.Code = errorResponse.Metadata["Code"];

                return(ex);
            }

            if (errorResponse.Code != null && errorResponse.Code.Equals("RequestTimeoutException"))
            {
                RequestTimeoutException ex = new RequestTimeoutException(errorResponse.Message, innerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, statusCode);

                ex.Type = errorResponse.Metadata["Type"];

                ex.Code = errorResponse.Metadata["Code"];

                return(ex);
            }

            if (errorResponse.Code != null && errorResponse.Code.Equals("ServiceUnavailableException"))
            {
                ServiceUnavailableException ex = new ServiceUnavailableException(errorResponse.Message, innerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, statusCode);

                ex.Type = errorResponse.Metadata["Type"];

                ex.Code = errorResponse.Metadata["Code"];

                return(ex);
            }

            if (errorResponse.Code != null && errorResponse.Code.Equals("InvalidParameterValueException"))
            {
                InvalidParameterValueException ex = new InvalidParameterValueException(errorResponse.Message, innerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, statusCode);

                ex.Type = errorResponse.Metadata["Type"];

                ex.Code = errorResponse.Metadata["Code"];

                return(ex);
            }

            return(new AmazonGlacierException(errorResponse.Message, innerException, errorResponse.Type, errorResponse.Code, errorResponse.RequestId, statusCode));
        }
            /// <summary>
            /// Block the calling thread until the <b>IRequest</b> is completed
            /// successfully, completed unsuccessfully, canceled, or a timeout
            /// occurs.
            /// </summary>
            /// <param name="millis">
            /// The number of milliseconds to wait for the result of the
            /// <b>IRequest</b>; pass zero to block the calling thread
            /// indefinitely.
            /// </param>
            /// <returns>
            /// The <b>IResponse</b>.
            /// </returns>
            /// <exception cref="InvalidOperationException">
            /// If the <b>IRequest</b> is cancelled, a timeout occurs, or the
            /// waiting thread is interrupted.
            /// </exception>
            public virtual IResponse WaitForResponse(long millis)
            {
                Exception e = null;

                if (millis == -1L)
                {
                    millis = DefaultTimeoutMillis;
                }

                if (millis <= 0L || millis > int.MaxValue)
                {
                    lock (this)
                    {
                        while (!IsClosed)
                        {
                            try
                            {
                                Monitor.Wait(this);
                            }
                            catch (Exception caught) // only ThreadInterruptedException can be caught here
                            {
                                e = caught;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    lock (this)
                    {
                        long start  = -1L;
                        long remain = millis;

                        while (!IsClosed)
                        {
                            if (start < 0L)
                            {
                                start = DateTime.UtcNow.Ticks / 10000;
                            }

                            try
                            {
                                Monitor.Wait(this, (int)remain);
                            }
                            catch (Exception caught) // only ThreadInterruptedException can be caught here
                            {
                                e = caught;
                                break;
                            }

                            if (IsClosed)
                            {
                                break;
                            }
                            else if ((remain -= Math.Max(DateTime.UtcNow.Ticks / 10000 - start, 0L)) <= 0L)
                            {
                                e = new RequestTimeoutException("request timed out after " + millis + " millis");
                                break;
                            }
                        }
                    }
                }

                // COH-6105 - Process exceptions outside of the synchronized blocks
                if (e != null)
                {
                    Cancel(e);
                    if (!(e is RequestTimeoutException))
                    {
                        Thread.CurrentThread.Interrupt();
                        throw e;
                    }
                }
                return(Response);
            }
예제 #8
0
        /// <summary>
        /// 发布一个请求。
        /// </summary>
        /// <typeparam name="TMessage">消息类型。</typeparam>
        /// <param name="bus">总线。</param>
        /// <param name="message">消息。</param>
        /// <param name="configurator">请求超时相关的配置动作。</param>
        /// <exception cref="ArgumentNullException"><paramref name="bus"/> 或 <paramref name="message"/> 为null。</exception>
        /// <exception cref="RequestTimeoutException">请求超时。</exception>
        /// <returns>是否成功。</returns>
        public static object PublishRequest <TMessage>(this IBus bus, TMessage message, Action <TimeoutConfigurator> configurator) where TMessage : MessageBase
        {
            if (bus == null)
            {
                throw new ArgumentNullException("bus");
            }
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }
            if (configurator == null)
            {
                throw new ArgumentNullException("configurator");
            }

            //初始化超时配置。
            var timeoutConfigurator = new TimeoutConfigurator();

            configurator(timeoutConfigurator);

            //任务起始时间。
            var startDateTime = DateTime.Now;
            //同步锁。
            var    autoResetEvent = new AutoResetEvent(false);
            object result         = null;

            //开始请求。
            bus.PublishRequest(message, c => c.Handle(responseMessage =>
            {
                try
                {
                    var exception = responseMessage.Exception;
                    if (exception != null)
                    {
                        throw new Exception("请求接收方处理程序发生了异常。", exception);
                    }
                    result = responseMessage.Result;
                }
                finally
                {
                    //取消线程锁定。
                    autoResetEvent.Set();
                }
            }));

            //等待线程。
            autoResetEvent.WaitOne(timeoutConfigurator.TimeoutTime);

            if (DateTime.Now.Subtract(startDateTime) <= timeoutConfigurator.TimeoutTime)
            {
                return(result);
            }

            //如果超时则抛出超时异常。
            var timeoutException = new RequestTimeoutException(message);

            if (timeoutConfigurator.TimeoutAction == null)
            {
                return(result);
            }
            if (!timeoutConfigurator.TimeoutAction(timeoutException))
            {
                throw timeoutException;
            }

            return(result);
        }