Повторите запрос, если первый не удался - PullRequest
0 голосов
/ 26 июня 2009

Я использую веб-службу xml в своем веб-приложении, и иногда удаленный сервер не отвечает вовремя. Мне пришла в голову идея повторного запроса, если первая попытка не удалась. Чтобы предотвратить цикл, я хочу ограничить количество одновременных запросов на 2. Я хочу получить мнение, если то, что я сделал ниже, в порядке и будет работать так, как я ожидаю.

public class ScEngine
{
    private int _attemptcount = 0;
    public int attemptcount
    {
        get
        {
            return _attemptcount;
        }
        set
        {
            _attemptcount = value;
        }
    }

    public DataSet GetStat(string q, string job)
    {

        try
        {
           //snip....
            attemptcount += attemptcount;
            return ds;

        }
        catch
        {
            if (attemptcount>=2)
            {
           return null;
            }
            else
            {
                return GetStat(q, job);
            }

        }

    }
}

Ответы [ 6 ]

1 голос
/ 13 июля 2009

Проверьте эту ссылку. Это отличный способ обработки повторов и таймаутов. http://timross.wordpress.com/2008/02/10/implementing-the-circuit-breaker-pattern-in-c/

1 голос
/ 26 июня 2009
public class ScEngine
{
    public DataSet GetStat(string q, string job)
    {
        int attemptCount;
        while(attemptCount < 2)
        {
            try
            {
                attemptCount++;
                var ds = ...//web service call
                return ds;
            }
            catch {}
        }
        //log the error
        return null;
    }
}
1 голос
/ 26 июня 2009

Вы забыли увеличить количество попыток. Кроме того, если при втором запуске возникнет ошибка, она не будет перехвачена (таким образом, станет необработанным исключением).

0 голосов
/ 26 июня 2009

Вот версия, которая не использует рекурсию, но достигает того же результата. Сюда также входит задержка, чтобы вы могли дать серверу время на восстановление, если он работает.

    /// <summary>
    /// The maximum amount of attempts to use before giving up on an update, delete or create
    /// </summary>
    private const int MAX_ATTEMPTS = 2;

    /// <summary>
    /// Attempts to execute the specified delegate with the specified arguments.
    /// </summary>
    /// <param name="operation">The operation to attempt.</param>
    /// <param name="arguments">The arguments to provide to the operation.</param>
    /// <returns>The result of the operation if there are any.</returns>
    public static object attemptOperation(Delegate operation, params object[] arguments)
    {
        //attempt the operation using the default max attempts
        return attemptOperation(MAX_ATTEMPTS, operation, arguments);
    }

    /// <summary>
    /// Use for creating a random delay between retry attempts.
    /// </summary>
    private static Random random = new Random();

    /// <summary>
    /// Attempts to execute the specified delegate with the specified arguments.
    /// </summary>
    /// <param name="operation">The operation to attempt.</param>
    /// <param name="arguments">The arguments to provide to the operation.</param>
    /// <param name="maxAttempts">The number of times to attempt the operation before giving up.</param>
    /// <returns>The result of the operation if there are any.</returns>
    public static object attemptOperation(int maxAttempts, Delegate operation, params object [] arguments)
    {
        //set our initial attempt count
        int attemptCount = 1;

        //set the default result
        object result = null;

        //we've not succeeded yet
        bool success = false;

        //keep trying until we get a result
        while (success == false)
        {
            try
            {
                //attempt the operation and get the result
                result = operation.DynamicInvoke(arguments);
                //we succeeded if there wasn't an exception
                success = true;
            }
            catch
            {
                //if we've got to the max attempts and still have an error, give up an rethrow it
                if (attemptCount++ == maxAttempts)
                {
                    //propogate the exception
                    throw;
                }
                else
                {
                    //create a random delay in milliseconds
                    int randomDelayMilliseconds = random.Next(1000, 5000);
                    //sleep for the specified amount of milliseconds
                    System.Threading.Thread.Sleep(randomDelayMilliseconds);
                }
            }
        }

        //return the result
        return result;
    }
0 голосов
/ 26 июня 2009

Вы не хотите решать это таким образом. Вы просто увеличите нагрузку на серверы и увеличите время ожидания.

Вы можете увеличить время ожидания веб-службы через httpRuntime . Веб-сервисы обычно возвращают много данных за один вызов, поэтому я часто делаю это. Не забудьте увеличить время ожидания клиента на стороне клиента.

0 голосов
/ 26 июня 2009

Я бы не стал возвращаться, чтобы повторить попытку. Кроме того, я не поймаю и проигнорирую все исключения. Я бы узнал, какие исключения указывают на ошибку, которую следует повторить, и перехватил бы ее. Вы будете игнорировать серьезные ошибки, так как ваш код стоит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...