当使用Polly时,在VS调试器中报告了“Exception User-Unhandled”的错误

7

我正在使用Polly来捕获在调用普特尼鲍尔地理编码服务时的异常。我正在使用一个g1client库,它会抛出MessageProcessingException异常。我已经将该调用包装在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个地址进行处理。下一次运行将在不到一秒钟内处理该请求,但是第一次不起作用。


取消选中这个 Visual Studio 选项,问题就会消失:选项 > 调试 > 通用 > 启用仅限我的代码。 - Theodor Zoulias
1个回答

22

简而言之,你只是在看到 Visual Studio 调试器在异常时中断的情况。

你可能会误解 Visual Studio 调试器(本质上令人困惑的)术语未处理的用户异常为整个执行代码库都未处理该异常;但实际情况并非如此。

在这种情况下,未处理的用户异常意味着首先通过 Polly 策略之外的其他方式 处理了该异常。

首先,Visual Studio 将您正在调试的代码分为“我的代码”(即“用户代码”)和“非用户代码”。在您的情况下,Polly 和 Geocoder 库将被归类为“非用户代码”。

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

Visual Studio 默认中断以便让您看到触发异常的行(即使随后的代码会处理它...)。因此,根据调试器的设置,您似乎正在看到 Visual Studio 中断,即使异常将按照 Polly 策略的配置进行处理。只需在调试器中按 F5/继续,后续代码将恢复。

您还可以按照本文档中告诉调试器在未处理的用户异常上继续执行标题下的说明更改此行为

您可以通过检查行为来进一步验证 Polly 策略是否起作用:System.Diagnostics.Debug.WriteLine("Exception being retried" + exception);。如果正在调用重试,您应该会看到来自该行的输出,或者如果在该行上设置了断点,则可以看到它被击中。
最后,如果所有配置的重试都已耗尽,则 Polly 重试策略会 重新引发任何最终异常。这是有意的 - 表示那种情况,并不是失败。
对于此,您已经正确使用了 try {...} catch (MessageProcessingException ex){...},但由于 Polly 最初捕获了该异常,因此调试器可能再次将其错误地标记为“未处理的用户异常”。

Visual Studio调试器让我认为异常没有被正确处理。实际上,Polly策略正确地多次重试了调用。对我来说,这进一步混淆了另一个问题,即在再次调用之前我的geocoderService对象没有完全重置。一旦我重新初始化了geocoderService对象,一切都正常了。我也没有看到System.Diagnostics.Debug.WriteLine消息,因为我没有在库构建部分中选中定义DEBUG常量。您的解释让我明白它应该这样做!非常好的解释! - user2197446

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接