首页 > 解决方案 > Polly 强制超时后任务仍在运行

问题描述

我正在尝试使用 Polly 和 Refit 实现重试/超时过程来访问 Web 服务。我有 10 秒的超时策略(Polly.Timeout.TimeoutRejectedException on timeout)。我有 2 次尝试的重试策略。我有一个userCancellationToken可以被用户取消的。如果我没有设置 Polly 超时策略,客户端默认超时 100 秒后System.IO.IOException

虽然这段代码基本上可以工作,但我有一些问题:

1)我的代码大部分是正确的吗?

2)如果我的超时时间为 10 秒,并且我强制我的服务器在 15 秒内回答,作为超时测试,此代码正确执行 3 次尝试,每次 10 秒然后失败,但几秒钟后我显示 3“成功后。 ..”,这意味着任务仍在运行并等待数据,即使 Polly 取消了它。如何取消正在运行的任务?

3)如果我的服务器无法访问,我会System.Net.Sockets.SocketException在 4 秒后得到一个。如何减少此超时?

        var timeOutPolicy = Policy
            .TimeoutAsync(
                10,
                TimeoutStrategy.Pessimistic);

        var retryPolicy = Policy
          .Handle<Exception>()              
          .RetryAsync(2, (exception, attempt) =>
          {                  
              sw.Stop();
              progress.Report($"Error after {sw.Elapsed}");
              progress.Report($"New attempt {attempt}");

              if (exception.InnerException is System.Net.Sockets.SocketException)
              {
                  progress.Report("Catched: SocketException (No server running or not reachable)");                      
              }
              if (exception.InnerException is System.IO.IOException)
              {
                  progress.Report("Catched: IOException (normal timeout)");                      
              }
              if (exception is Polly.Timeout.TimeoutRejectedException)
              {
                  progress.Report("Catched: Polly Exception (timeout set by Polly)");
              }                  
              if (exception.InnerException is ApiException) progress.Report("Catched: ApiException");
          });

        var policyWrap = Policy.WrapAsync(retryPolicy, timeOutPolicy);

        try
        {
            await policyWrap.ExecuteAsync(async (ct) =>
            {
                sw.Restart();                    

                progress.Report("Execute");                    

                var api = RestService.For<ICTServerApi>("http://localhost:3105/json/reply/ReqUtenti");

                respUtenti = await api.GetUtentiAsync(reqUtenti, userCancellationToken).ConfigureAwait(false);

                sw.Stop();
                progress.Report($"Success after {sw.Elapsed}");
            }, userCancellationToken).ConfigureAwait(false);
        }            

谢谢!

标签: c#.net-coredotnet-httpclientpollyrefit

解决方案


推荐阅读