Какой правильный код для Microsoft.Practices.TransientFaultHandling.RetryPolicy? - PullRequest
1 голос
/ 28 марта 2012

Я использую следующий код:

Создайте политику повторных попыток, при возникновении ошибки повторите попытку через 1 секунду, затем подождите 3 секунды, затем 5 секунд. на основе Azure SLA повторная попытка в течение 10 секунд должна быть успешной (без ограничения, я уверен в этом. потому что ошибка даже происходит на уникальном разделе и таблице, в которой еще нет трафика)

var retryStrategy = new Incremental(3, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
var FaultHandlingRetryPolicy = new RetryPolicy<StorageTransientErrorDetectionStrategy>(retryStrategy);

Затем я использую этот код для получения данных

FaultHandlingRetryPolicy .ExecuteAction(() =>
        {
            var results = (from q in Query select new q).ToList();
        });

Я НЕ ЗНАЮ, если его повторить или нет, потому что журнал ошибок не отображается

Ошибка:

System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 70.37.127.112:443
   at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
   --- End of inner exception stack trace ---
   at System.Net.HttpWebRequest.GetResponse()
   at System.Data.Services.Client.QueryResult.Execute()
   at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, QueryComponents queryComponents)
   at System.Data.Services.Client.DataServiceQuery`1.Execute()
   at System.Data.Services.Client.DataServiceQuery`1.GetEnumerator()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Microsoft.Practices.TransientFaultHandling.RetryPolicy.<>c__DisplayClass1.<ExecuteAction>b__0()
   at Microsoft.Practices.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)

Пожалуйста, дайте мне знать, если этот код будет повторяться, спасибо

1 Ответ

5 голосов
/ 29 марта 2012

При настройке политики повторных попыток вы указываете класс, который будет управлять удалениями, в вашем случае это StorageTransientErrorDetectionStrategy.

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

Чтобы реально отслеживать количество повторов, вы можете использовать код, подобный следующему:

FaultHandlingRetryPolicy.Retrying += (obj, eventArgs) =>
            {
                Console.Writeline("Retrying, CurrentRetryCount = {0} , Exception = {1}", eventArgs.CurrentRetryCount, eventArgs.LastException.Message);
            };

Обновление

Вы можете создать свою собственную стратегию обработки ошибок, подобную этой, и использовать ее вместо стандартной. НО вам придется настроить ошибки в соответствии с вашим сценарием, они сработали для меня.

    public class CustomSqlAzureTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy
    {
        private readonly SqlAzureTransientErrorDetectionStrategy _normalStrategy =
            new SqlAzureTransientErrorDetectionStrategy();

        public bool IsTransient(Exception ex)
        {
            if (_normalStrategy.IsTransient(ex))
                return true;

            //do our custom logic
            if (ex is SqlException)
            {
                var sqEx = ex as SqlException;
                if (sqEx.Message.Contains("The timeout period elapsed prior to completion of the operation or the server is not responding") ||
                    sqEx.Message.Contains("An existing connection was forcibly closed by the remote host") ||
                    sqEx.Message.Contains("The service has encountered an error processing your request. Please try again") ||
                    sqEx.Message.Contains("Timeout expired") ||
                    sqEx.Message.Contains("was deadlocked on lock resources with another process and has been chosen as the deadlock victim") ||
                    sqEx.Message.Contains("A transport-level error has occurred when receiving results from the server"))
                {                        
                    return true;
                }
            }

            return false;
        }
    }
...