.NET Framework 4.8下Azure.Storage库如何实现Blob重试日志记录?
升级Azure.Storage库实现Blob上传重试与日志记录
我有一个基于.NET Framework 4.8的老旧C# WinForms项目,原使用Microsoft.WindowsAzure.Storage库,现计划升级至最新的Azure.Storage库。原项目通过Microsoft.WindowsAzure.Storage.OperationContext记录Blob上传的重试及请求完成日志,目前已在BlobClientOptions中配置了重试次数,但不清楚如何在新库中实现类似的重试、错误及成功日志记录,且未找到相关的完善文档。
旧代码示例
var context = new OperationContext(); context.ClientRequestID = myid; //"some request id"; context.Retrying += (sender, args) => { int retryCnt = context.RequestResults.Count; ErrorMessage("Upload failed. Start Retry " + retryCnt + " for BLOB: " + blobName, myid); }; // define action when request is completed -> the request is also completed when the upload failed context.RequestCompleted += (sender, args) => { /* Collect operation completion information */ if (args.Response != null) { DebugMessage("Upload completed for BLOB " + blobName, myid); } else { int retryCnt = context.RequestResults.Count - 1; ErrorMessage("Upload failed (Retry " + retryCnt + ") for BLOB " + blobName, myid); } };
已实现的新库重试配置
BlobContainerClient container = null; var options = new BlobClientOptions(); options.Retry.MaxRetries = 4; /* Create Handle to storage container using the sas to identify */ try { container = new BlobContainerClient(new Uri(sasToken),options); } catch (Exception ex) { ErrorMessage("container reference couldn't be set" + ex.Message, String.Empty); }
解决方案
新的Azure.Storage库没有直接对应OperationContext的类,但可以通过自定义重试策略和请求处理器实现相同的日志需求,具体步骤如下:
1. 自定义重试策略记录重试事件
继承RetryPolicy类,重写ShouldRetryAsync方法,在重试触发时写入日志:
public class LoggingRetryPolicy : RetryPolicy { private readonly string _blobName; private readonly string _requestId; public int RetryCount { get; private set; } = 0; public LoggingRetryPolicy(RetryPolicy basePolicy, string blobName, string requestId) : base(basePolicy.MaxRetries, basePolicy.Delay, basePolicy.MaxDelay, basePolicy.Mode) { _blobName = blobName; _requestId = requestId; } public override async ValueTask<bool> ShouldRetryAsync( int attemptNumber, Exception exception, CancellationToken cancellationToken) { bool shouldRetry = await base.ShouldRetryAsync(attemptNumber, exception, cancellationToken); if (shouldRetry) { RetryCount++; ErrorMessage($"Upload failed. Start Retry {RetryCount} for BLOB: {_blobName}", _requestId); } return shouldRetry; } }
2. 添加请求处理器记录请求完成事件
通过HttpPipelinePolicy拦截请求的完成状态,判断成功或失败并写入日志:
public class RequestLoggingPolicy : HttpPipelinePolicy { private readonly string _blobName; private readonly string _requestId; public RequestLoggingPolicy(string blobName, string requestId) { _blobName = blobName; _requestId = requestId; } public override async ValueTask ProcessAsync( HttpPipelineMessage message, ReadOnlyMemory<HttpPipelinePolicy> pipeline, CancellationToken cancellationToken) { // 执行后续管道处理 await ProcessNextAsync(message, pipeline, cancellationToken); // 请求完成后判断状态并记录日志 if (message.Response.Status >= 200 && message.Response.Status < 300) { DebugMessage($"Upload completed for BLOB {_blobName}", _requestId); } else { var retryPolicy = message.Pipeline.GetRetryPolicy() as LoggingRetryPolicy; int retryCount = retryPolicy?.RetryCount ?? 0; ErrorMessage($"Upload failed (Retry {retryCount}) for BLOB {_blobName}", _requestId); } } }
3. 配置BlobClientOptions并应用自定义策略
创建容器时替换默认重试策略,添加请求日志处理器:
var myid = "some request id"; var blobName = "your-target-blob-name"; var options = new BlobClientOptions(); // 基于默认指数退避策略创建带日志的重试策略 var baseRetry = new ExponentialBackoffRetryPolicy(4, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10)); options.Retry.CustomPolicy = new LoggingRetryPolicy(baseRetry, blobName, myid); // 添加请求日志处理器 options.AddPolicy(new RequestLoggingPolicy(blobName, myid), HttpPipelinePosition.PerCall); BlobContainerClient container = null; try { container = new BlobContainerClient(new Uri(sasToken), options); } catch (Exception ex) { ErrorMessage($"container reference couldn't be set: {ex.Message}", string.Empty); }
补充说明
- 如果需要全局复用日志策略,可以将请求ID、BlobName通过
HttpPipelineMessage.Properties字典传递,避免每次创建策略时传入参数。 - 不同Blob操作(上传、下载等)可以在调用具体方法前动态添加对应的日志策略。
内容的提问来源于stack exchange,提问作者becky
相关产品推荐
相关产品推荐

