4

I'm using the standard example from microsoft for inserting new entitys to a table. Is there a way to track if a retry was performed?

Code:

CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("people");
CustomerEntity customer1 = new CustomerEntity("Harp", "Walter");
TableOperation insertOperation = TableOperation.Insert(customer1);
table.Execute(insertOperation);

With TransientFaultHandlingFramework it was easy to do:

var retryPol = new RetryPolicy<SqlAzureTransientErrorDetectionStrategy>(retryStrategy); 
retryPol.Retrying += (obj, eventArgs) =>
{
var msg = String.Format("Retrying, CurrentRetryCount = {0} , Delay = {1}, Exception = {2}", eventArgs.CurrentRetryCount, eventArgs.Delay, eventArgs.LastException.Message);
System.Diagnostics.Debug.WriteLine(msg);
};
4

2 回答 2

5

您可以使用企业库瞬态故障处理应用程序块,如Rob 的回答中所述:

var retryPol = new RetryPolicy<StorageTransientErrorDetectionStrategy>(retryStrategy); 
retryPol.Retrying += (obj, eventArgs) =>
{
    var msg = String.Format("Retrying, CurrentRetryCount = {0} , Delay = {1}, Exception = {2}", eventArgs.CurrentRetryCount, eventArgs.Delay, eventArgs.LastException.Message);
    System.Diagnostics.Debug.WriteLine(msg);
};

var options = new TableRequestOptions { RetryPolicy = new RetryPolicies.NoRetry() };

CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("people");
CustomerEntity customer1 = new CustomerEntity("Harp", "Walter");
TableOperation insertOperation = TableOperation.Insert(customer1);

retryPol.ExecuteAction<TableResult>(() => { return table.Execute(insertOperation, options); });

如果您更喜欢专门使用 Windows Azure 存储客户端库,则可以创建引发事件的自定义重试策略,如下所示:

public class EventExponentialRetry : IRetryPolicy
{
    private static readonly TimeSpan DefaultClientBackoff = TimeSpan.FromSeconds(4.0);
    private const int DefaultClientRetryCount = 3;
    private TimeSpan deltaBackoff;
    private int maximumAttempts;
    private ExponentialRetry retry;

    public event EventHandler<RetryEventArgs> RaiseRetryEvent;

    public EventExponentialRetry()
    {
        Initialize(DefaultClientBackoff, DefaultClientRetryCount);
    }

    public EventExponentialRetry(TimeSpan deltaBackoff, int maxAttempts)
    {
        Initialize(deltaBackoff, maxAttempts);
    }

    private void Initialize(TimeSpan deltaBackoff, int maxAttempts)
    {
        this.deltaBackoff = deltaBackoff;
        this.maximumAttempts = maxAttempts;
        retry = new ExponentialRetry(this.deltaBackoff, this.maximumAttempts);
    }

    public IRetryPolicy CreateInstance()
    {
        EventExponentialRetry newInstance = new EventExponentialRetry(this.deltaBackoff, this.maximumAttempts);
        newInstance.RaiseRetryEvent = this.RaiseRetryEvent;
        return newInstance;
    }

    public bool ShouldRetry(int currentRetryCount, int statusCode, Exception lastException, out TimeSpan retryInterval, OperationContext operationContext)
    {
        bool shouldRetry = retry.ShouldRetry(currentRetryCount, statusCode, lastException, out retryInterval, operationContext);
        if (shouldRetry)
        {
            OnRaiseRetryEvent(new RetryEventArgs(currentRetryCount, statusCode, lastException, retryInterval, operationContext));
        }
        return shouldRetry;
    }

    protected virtual void OnRaiseRetryEvent(RetryEventArgs e)
    {
        // Make a temporary copy of the event to avoid possibility of 
        // a race condition if the last subscriber unsubscribes 
        // immediately after the null check and before the event is raised.
        EventHandler<RetryEventArgs> handler = RaiseRetryEvent;

        // Event will be null if there are no subscribers.
        if (handler != null)
        {
            // Use the () operator to raise the event.
            handler(this, e);
        }
    }
}

有关完整示例,请参阅CustomAzureStorageRetryPolicySample GitHub 项目

于 2013-07-04T18:21:09.343 回答
1

您可以将相同的企业瞬态故障处理框架与您的表存储(及其关联的重试通知)一起使用。

为此,您禁用默认的表存储瞬时故障处理并改用企业存储故障处理。

var retryPol = new RetryPolicy<StorageTransientErrorDetectionStrategy>(retryStrategy); 
retryPol.Retrying += (obj, eventArgs) =>
{
    var msg = String.Format("Retrying, CurrentRetryCount = {0} , Delay = {1}, Exception = {2}", eventArgs.CurrentRetryCount, eventArgs.Delay, eventArgs.LastException.Message);
    System.Diagnostics.Debug.WriteLine(msg);
};

var options = new TableRequestOptions { RetryPolicy = new RetryPolicies.NoRetry() };

CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("people");
CustomerEntity customer1 = new CustomerEntity("Harp", "Walter");
TableOperation insertOperation = TableOperation.Insert(customer1);

retryPol.ExecuteAction<TableResult>(() => { return table.Execute(insertOperation, options); });
于 2013-07-04T22:32:38.810 回答