コード例 #1
0
        /// <summary>
        /// Invokes service method that returns a value of type T.
        /// </summary>
        protected T Invoke <T>(ServiceMethod <T> method)
        {
            const int maxRetryCount = 1;
            int       retryCount    = 0;

            while (true)
            {
                var client = _AcquireClient();
                try
                {
                    return(method.Invoke(client));
                }
                catch (Exception e)
                {
                    if (ProxyAuthenticationErrorHandler.HandleError(e))
                    {
                        continue;
                    }

                    var isTokenError = _IsTokenError(e);
                    if (retryCount >= maxRetryCount || !isTokenError)
                    {
                        if (ServiceHelper.IsCommunicationError(e))
                        {
                            throw ServiceHelper.CreateCommException(
                                      _connection.Title,
                                      e);
                        }

                        throw;
                    }

                    if (isTokenError)
                    {
                        _connection.GenerateToken();
                        _CloseClient(client);
                        client = null;
                    }

                    ++retryCount;
                }
                finally
                {
                    _ReleaseClient(client);
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Attempts to prepare for retrying request sending upon catching the
        /// specified exception.
        /// </summary>
        /// <param name="exception">The exception caused failure of the previous
        /// request sending.</param>
        /// <returns>True if and only if the request sending could be repeated.</returns>
        private bool _PrepareRetry(Exception exception)
        {
            var restException = exception as RestException;

            if (restException != null)
            {
                return(false);
            }

            if (ProxyAuthenticationErrorHandler.HandleError(exception))
            {
                return(true);
            }

            if (_IsTransientError(exception))
            {
                Thread.Sleep(RETRY_WAIT_TIME);

                return(true);
            }

            return(false);
        }
コード例 #3
0
        /// <summary>
        /// Handles AsyncCompleted event results.
        /// </summary>
        /// <returns>
        /// Returns true if the operation is completed, false if it's retried.
        /// </returns>
        protected bool IsAsyncCompleted(object sender, AsyncCompletedEventArgs args,
                                        out AsyncCompletedEventArgs outArgs)
        {
            outArgs = null;

            Guid      id        = Guid.Empty;
            Exception error     = args.Error;
            object    userState = null;

            bool isCompleted = true;

            try
            {
                TClient client = (TClient)sender;
                _DecrementAsyncRefCount(client);

                if (args.UserState == null)
                {
                    throw new InvalidOperationException();
                }

                id = (Guid)args.UserState;

                AsyncContext ctx = null;
                if (!_asyncContextMap.TryGetValue(id, out ctx))
                {
                    throw new InvalidOperationException();
                }

                userState = ctx.UserState;
                if (_IsAsyncFailed(args))
                {
                    bool needToRetry =
                        ctx.RetryCount == 0 &&
                        _IsTokenError(args.Error);

                    if (ProxyAuthenticationErrorHandler.HandleError(args.Error))
                    {
                        needToRetry = true;
                    }

                    if (needToRetry)
                    {
                        _connection.GenerateToken(); // update token
                    }
                    if (needToRetry || client.State == CommunicationState.Faulted)
                    {
                        _CloseClient(client);

                        // do retry if needed
                        if (needToRetry)
                        {
                            client = _AcquireClient();
                            _IncrementAsyncRefCount(client);
                            ctx.RetryMethod(client);
                            isCompleted = false;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                error = e;
            }

            if (isCompleted)
            {
                if (error != null)
                {
                    error = _ConvertCommException(error);
                }

                _asyncContextMap.Remove(id);
                outArgs = new AsyncCompletedEventArgs(error, args.Cancelled, userState);
            }

            return(isCompleted);
        }