You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:45:36