使用Flurl与Polly异步POST时,重试导致FileContent已释放的问题求助
解决Flurl+Polly异步POST重试时FileContent已释放的问题
问题根源:FileContent属于HttpContent派生类,HttpClient在发送请求后会自动释放它。你现在提前创建好httpContent实例,第一次请求完成(不管成功还是失败触发重试)后,这个实例已经被释放,重试时再复用就会抛出ObjectDisposedException。
解决办法:把创建FileContent的逻辑放到Polly的ExecuteAsync委托内部,让每次重试都生成全新的FileContent实例。
修改后的核心代码如下:
var endpoint = $"api endpoint here"; if (!File.Exists(filePath)) { return Task.CompletedTask; } return _statusRetryPolicy .StatusAsyncRetryPolicy() .ExecuteAsync(async () => { // 每次重试都重新创建FileContent var fileBytesLength = _fileSystem.FileInfo.FromFileName(filePath).Length; var httpContent = new Flurl.Http.Content.FileContent(filePath, (int)fileBytesLength); return await endpoint .WithOAuthBearerToken(accessToken) .WithTimeout(TimeSpan.FromMinutes(timeOutMinutes)) .WithHeader("Content-Type", "application/zip") .OnError((flurlCall) => { _logger.LogError(flurlCall.Exception, flurlCall.Exception.Message); }) .PostAsync(httpContent); });
重试策略代码保持不变:
public AsyncRetryPolicy StatusAsyncRetryPolicy() => Policy .Handle<FlurlHttpException>(RetryPolicyHelpers.IsTransientError) .WaitAndRetryAsync(5, retryAttempt => { var nextAttemptIn = TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)); _logger.LogWarning($"StatusRetryPolicy: Retry attempt {retryAttempt} to make request. Next try in {nextAttemptIn.TotalSeconds} seconds."); return nextAttemptIn; });
关键注意点:
- 所有和HttpContent相关的初始化逻辑都要放在重试执行的委托里,确保每次重试都有全新的可用实例
- 委托要加上
async和await,保证异步逻辑正确执行
内容的提问来源于stack exchange,提问作者Little Geeza
相关产品推荐
相关产品推荐

