Polly重试后触发未处理异常,System.Private.CoreLib.dll介入原因及解决
Polly重试耗尽后未处理异常问题分析与解决
问题原因
Polly重试策略的默认行为是:当配置的重试次数耗尽后,会重新抛出最后一次触发重试的异常,不再进行捕获处理。此时CLR(公共语言运行时)会通过System.Private.CoreLib.dll这个.NET核心库来处理未被应用代码捕获的异常——这不是DLL主动介入,而是Polly重试结束后将异常抛回给了CLR,由核心库负责执行未处理异常的抛出流程。
解决方法
针对该问题,有三种常见处理方式:
1. 添加回退策略(Fallback)
在重试策略后附加回退策略,捕获重试耗尽后的最终异常,执行自定义处理(如日志记录、返回默认结果):
// 构建重试策略 var retryPolicy = Policy .Handle<ApplicationException>() .Retry(3); // 构建回退策略 var fallbackPolicy = Policy .Handle<ApplicationException>() .Fallback(() => { Console.WriteLine("重试耗尽,执行回退逻辑"); // 可返回默认值或执行其他业务处理 }, ex => { Console.WriteLine($"捕获最终异常:{ex.Message}"); }); // 组合策略:先执行重试,重试耗尽后触发回退 var combinedPolicy = fallbackPolicy.Wrap(retryPolicy); // 执行受保护的业务操作 combinedPolicy.Execute(() => { throw new ApplicationException("模拟业务异常"); });
2. 外层添加try-catch捕获
在调用Polly策略的代码外层直接添加try-catch块,处理重试耗尽后的异常:
var retryPolicy = Policy .Handle<ApplicationException>() .Retry(3); try { retryPolicy.Execute(() => { throw new ApplicationException("模拟业务异常"); }); } catch (ApplicationException ex) { Console.WriteLine($"重试耗尽后捕获异常:{ex.Message}"); // 自定义异常处理逻辑 }
3. 调整重试策略配置
- 增加重试次数:如果业务允许,适当提高重试次数,避免快速耗尽重试配额
- 优化异常过滤:确保
Handle<T>覆盖所有需要重试的异常类型,避免遗漏导致异常提前跳出重试流程
附用户提供的相关信息
程序运行日志
[10:00:00] 开始执行操作 [10:00:00] 抛出异常:模拟异常 [10:00:00] Polly捕获异常,进行第1次重试 [10:00:01] 抛出异常:模拟异常 [10:00:01] Polly捕获异常,进行第2次重试 [10:00:02] 抛出异常:模拟异常 [10:00:02] Polly捕获异常,进行第3次重试 [10:00:03] 抛出异常:模拟异常 [10:00:03] 未处理异常:System.ApplicationException: 模拟异常
核心源码
using Polly; using System; namespace PollyTest { class Program { static void Main(string[] args) { var retryPolicy = Policy .Handle<ApplicationException>() .Retry(3); retryPolicy.Execute(() => { Console.WriteLine($"[{DateTime.Now:HH:mm:ss}] 抛出异常:模拟异常"); throw new ApplicationException("模拟异常"); }); } } }
Visual Studio调试输出
'PollyTest.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.25\System.Private.CoreLib.dll'. 'PollyTest.exe' (CoreCLR: clrhost): Loaded 'C:\Users\user\source\repos\PollyTest\PollyTest\bin\Debug\net6.0\PollyTest.dll'. [10:00:00] 抛出异常:模拟异常 Exception thrown: 'System.ApplicationException' in PollyTest.dll Polly捕获异常,进行第1次重试 [10:00:01] 抛出异常:模拟异常 Exception thrown: 'System.ApplicationException' in PollyTest.dll Polly捕获异常,进行第2次重试 [10:00:02] 抛出异常:模拟异常 Exception thrown: 'System.ApplicationException' in PollyTest.dll Polly捕获异常,进行第3次重试 [10:00:03] 抛出异常:模拟异常 Exception thrown: 'System.ApplicationException' in System.Private.CoreLib.dll 未处理的异常: System.ApplicationException: 模拟异常 at PollyTest.Program.<>c.<Main>b__0_0() in C:\Users\user\source\repos\PollyTest\PollyTest\Program.cs:line 14 at Polly.Retry.RetryEngine.Implementation[TResult](Func`1 action, Context context, CancellationToken cancellationToken, ExceptionPredicates shouldRetryExceptionResultPredicates, ResultPredicates`1 shouldRetryResultPredicates, Action`3 onRetry, Int32 permittedRetryCount, IEnumerable`1 sleepDurationsEnumerable, Func`4 sleepDurationProvider)
内容的提问来源于stack exchange,提问作者hlovdal
相关产品推荐
相关产品推荐

