C# 如何检查Polly的回复状态?

C# 如何检查Polly的回复状态?,c#,dotnet-httpclient,polly,C#,Dotnet Httpclient,Polly,我正在用下面的代码从一个url下载一个特定文件夹中的.tgz文件(最大100MB),它工作正常。我正在使用HttpClient和Polly进行超时和重试 private static HttpClient _httpClient = new HttpClient() { Timeout = TimeSpan.FromSeconds(5) }; private async Task<bool> Download(string fileUrl) { var config

我正在用下面的代码从一个url下载一个特定文件夹中的
.tgz
文件(最大100MB),它工作正常。我正在使用
HttpClient
Polly
进行超时和重试

private static HttpClient _httpClient = new HttpClient()
{
    Timeout = TimeSpan.FromSeconds(5)
};

private async Task<bool> Download(string fileUrl)
{
    var configs = await Policy
       .Handle<TaskCanceledException>()
       .WaitAndRetryAsync(retryCount: 3, sleepDurationProvider: i => TimeSpan.FromMilliseconds(300))
       .ExecuteAsync(async () =>
       {
           using (var httpResponse = await _httpClient.GetAsync(fileUrl).ConfigureAwait(false))
           {
               httpResponse.EnsureSuccessStatusCode();
               return await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
           }
       }).ConfigureAwait(false);

    File.WriteAllBytes("Testing/data.tgz", configs);
    return true;
}
private static HttpClient\u HttpClient=new HttpClient()
{
超时=时间跨度。从秒(5)
};
专用异步任务下载(字符串文件URL)
{
var configs=等待策略
.Handle()
.WaitAndRetyaSync(retryCount:3,sleepDurationProvider:i=>TimeSpan.FromMillics(300))
.ExecuteAsync(异步()=>
{
使用(var httpResponse=await _httpClient.GetAsync(fileUrl.ConfigureAwait(false))
{
httpResponse.EnsureAccessStatusCode();
返回await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
}
}).配置等待(错误);
文件.writealBytes(“Testing/data.tgz”,configs);
返回true;
}
正如您在上面的方法中所看到的,我总是返回true,但它是不正确的。我想做以下事情:

  • 如果由于某种原因,在重试x次后无法连接到URL,那么我希望返回false并记录为“无法与URL对话”
  • 另外,如果我不能创建文件或在磁盘上的文件中写入字节数组,那么我也要返回false。我不确定这件事什么时候会发生,但我想保护我们不受此影响。在我的例子中,这可能实现吗

对于第一个问题,我阅读了更多关于波利的信息,但找不到如何在x次重试后检查波利呼叫的响应,然后采取相应的行动。至于第二个问题——我不确定我们如何才能做到这一点。另外,由于我最近开始使用C#(可能是几周),我可能在上面的代码中出错,因此如果有更好的方法,请告诉我。

如果我理解您的问题,页面上有一个部分用于捕获响应

执行后:捕获结果或任何最终异常

var policyResult = await Policy
              .Handle<HttpRequestException>()
              .RetryAsync()
              .ExecuteAndCaptureAsync(() => DoSomethingAsync());
/*              
policyResult.Outcome - whether the call succeeded or failed         
policyResult.FinalException - the final exception captured, will be null if the call succeeded
policyResult.ExceptionType - was the final exception an exception the policy was defined to handle (like HttpRequestException above) or an unhandled one (say Exception). Will be null if the call succeeded.
policyResult.Result - if executing a func, the result if the call succeeded or the type's default value
*/
var policyResult=等待策略
.Handle()
.RetryAsync()
.ExecuteAndCaptureAync(()=>doSoSomethingAsync());
/*              
policyResult.Output-调用是否成功
policyResult.FinalException-如果调用成功,捕获的最终异常将为null
policyResult.ExceptionType-是最终的异常—策略定义要处理的异常(如上面的HttpRequestException)还是未处理的异常(如异常)。如果调用成功,则将为null。
Result-如果执行func,则为调用成功时的结果或类型的默认值
*/
更新

var policyResult = await Policy
   .Handle<TaskCanceledException>()
   .WaitAndRetryAsync(retryCount: 3, sleepDurationProvider: i => TimeSpan.FromMilliseconds(300))
   .ExecuteAndCaptureAsync(async () =>
   {
      using (var httpResponse = await _httpClient.GetAsync("Something").ConfigureAwait(false))
      {
         httpResponse.EnsureSuccessStatusCode();
         return await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
      }
   }).ConfigureAwait(false);

if (policyResult.Outcome == OutcomeType.Failure)
   return false;

try
{

    File.WriteAllBytes("Testing/data.tgz", policyResult.Result);      
    return true;
}
catch(Exception ex)
{  
    // usually you wouldn't want to catch ALL exceptions (in general), however this is updated from the comments in the chat
    // file operations can fail for lots of reasons, maybe best catch and log the results. However ill leave these details up to you
    // log the results
    return false
}
var policyResult=等待策略
.Handle()
.WaitAndRetyaSync(retryCount:3,sleepDurationProvider:i=>TimeSpan.FromMillics(300))
.ExecuteAndCaptureAync(异步()=>
{
使用(var httpResponse=await _httpClient.GetAsync(“某物”).ConfigureAwait(false))
{
httpResponse.EnsureAccessStatusCode();
返回await httpResponse.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
}
}).配置等待(错误);
if(policyResult.Output==OutcomeType.Failure)
返回false;
尝试
{
writealBytes文件(“Testing/data.tgz”,policyResult.Result);
返回true;
}
捕获(例外情况除外)
{  
//通常情况下,您不希望捕获所有异常(一般而言),但是这是从聊天室中的注释更新的
//由于很多原因,文件操作可能会失败,也许最好捕获并记录结果。不过,我将把这些细节留给您
//记录结果
返回错误
}

将其包装在
try catch
中,并在
catch
语句中返回
false
。我想无论如何都需要检查Polly的响应。不是吗@aepotI对Polly不太熟悉,但我猜如果出现问题,它肯定会抛出,这样你就可以抓住它了。调试它(用错误的参数打断它),您将看到是否抛出了一些异常,
返回false的原因。
是的,但我没有看到
结果
和我的
配置
变量上的其他属性,这就是我感到困惑的原因。我只需要弄清楚我的URL调用是否成功地从中获取了数据。可能所有重试都失败了,所以我想避免这种情况。@dragons
policyResult.output
,您也可以检查您的
policyResult.Result
是否为空。例如,您还需要什么其他信息?是的,我理解这一部分,但在我的情况下,我需要更改我的
策略
行吗?Bcoz到目前为止,我无法在我的
configs
变量上获取这些属性。看起来我可能需要更改一些内容。@dragons您需要使用
ExecuteAndCaptureAsync
not
ExecuteAsync
明白了。在尝试使用
executeAndCaptureAync
方法替换
executeEasync
之后,我遇到了一个编译错误。你认为你能为我的例子提供一个如何使用该方法的例子吗?这将帮助我更好地理解。