5

我在调用 Pittney Bowes Geocoder 服务时使用 Polly 捕获异常。我正在使用引发 MessageProcessingException 的 g1client 库。如果抛出此异常,我已将调用包装在 Polly 网络策略中以重试调用最多 3 次,但 Visual Studio 坚持认为异常是“用户未处理”我需要修改什么才能处理此异常? 我正在使用 Visual Studio 2017 社区版和 C# 4.6.1。

try
{
    var networkPolicy = Policy
                              .Handle<MessageProcessingException>()
                              .Or<Exception>()
                              .WaitAndRetry(
                                   3,
                                   retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
                                   (exception, timeSpan, context) =>
                                   {
                                       System.Diagnostics.Debug.WriteLine("Exception being retried" + exception);
                                   });
    geocoderResponse = networkPolicy.Execute(() => geocoderService.Process(geocoderRequest));
}
catch (MessageProcessingException ex)
{
    log.Error("MessageProcessingException calling the Geocoder service", ex);
    throw ex;
}
catch (Exception ex)
{
    log.Error("Exception calling the Geocoder service", ex);
    throw ex;
}

错误信息是:

g1client.MessageProcessingException occurred
  HResult=0x80131500
  Message=Unable to read data from the transport connection: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. Client timeout
  Source=g1client
  StackTrace:
   at g1client.UTF8Serializer.DeserializeHashtable(NetworkStream networkStream)
   at g1client.UTF8Serializer.GetMessage(NetworkStream networkStream)
   at g1client.SocketGatewayConnection.ProcessBytes(Byte[] bytesIn)
   at g1client.SocketGatewayConnection.Process(Message message)
   at g1client.RemoteService.Process(Message message)
   at Midas.Core.PBGeocoder.Geocoder.<>c__DisplayClass27_0.<Bulk2PassGeocode>b__2() in E:\Source Code\GitHub\Midas.Core\Midas.Core.PBGeocoder\Geocoder.cs:line 321
   at Polly.Policy.<>c__DisplayClass75_0`1.<Execute>b__0(CancellationToken ct)
   at Polly.Policy.<>c__DisplayClass27_0`1.<Execute>b__0(CancellationToken ct)
   at Polly.RetrySyntax.<>c__DisplayClass11_0.<WaitAndRetry>b__1(CancellationToken ct)
   at Polly.Retry.RetryEngine.Implementation[TResult](Func`2 action, CancellationToken cancellationToken, IEnumerable`1 shouldRetryExceptionPredicates, IEnumerable`1 shouldRetryResultPredicates, Func`1 policyStateFactory)

我还想追查为什么我会收到这个错误,所以任何帮助调试也很好。我只有在第一次使用大量请求调用服务时才得到它。在这种情况下,我发送了 1000 个地址进行处理。下一次运行请求将在一秒钟内处理,但第一次它不起作用。

4

1 回答 1

17

TL;DR 您只是看到 VS 调试器因异常而中断。

您可能正在理解 Visual Studio 调试器的(本质上令人困惑的)术语用户未处理的异常,这意味着执行代码库作为一个整体没有处理异常;不是这种情况。

在这种情况下,用户未处理的异常意味着异常首先由您的代码处理,而不是由您的代码处理- 这里是由 Polly 策略。

首先,Visual Studio 将您正在调试的代码分为'my code' aka 'user code' 和 'non-user code'。在您的场景中,Polly 和 Geocoder 库将被归类为“非用户代码”。

其次,默认情况下,Visual Studio 调试器会在“非用户代码”处理的异常上中断[+](但使用这个可能令人困惑和令人担忧的术语“用户未处理”!)。

默认情况下,Visual Studio 会中断 [+],以便您可以看到触发异常的行(即使后续代码会处理它......)。因此,听起来(调试器设置上的 dpdg)好像您正在看到 Visual Studio 中断,即使异常将按照 Polly 策略的配置进行处理。只需在调试器中按 F5/Continue,后面的代码就会恢复。

您还可以按照本文中标题“告诉调试器继续处理用户未处理的异常”下的说明更改此行为[+] 。

通过检查线路的行为,您可以进一步确定 Polly 策略是否有效System.Diagnostics.Debug.WriteLine("Exception being retried" + exception);。如果正在调用重试,您应该会看到该行的输出 - 或者如果您在其上设置断点看到它命中。


最后,如果所有配置的重试都已用尽,Polly 重试策略将重新引发任何最终异常。这是有意的——表明这种可能性——而不是失败。

您正确地try { ... } catch (MessageProcessingException ex) { ... }对此有一个,但调试器可能会再次误导性地标记最终异常“用户未处理”——即使你有一个 try-catch ——因为它最初被 Polly 捕获。

于 2017-05-19T21:25:36.363 回答