如何将自定义重试函数与业务函数整合为通用重试执行工具?
通用重试逻辑与业务函数整合方案
核心思路
用委托将业务逻辑与重试逻辑解耦,让通用重试函数适配任意业务场景,同时支持自定义「哪些异常需要重试」的规则,避免重复编写异常捕获和重试代码。
优化后的通用重试函数
public static T ExecuteWithRetry<T>(Func<T> operation, Func<Exception, bool> shouldRetry, out Exception lastException, T defaultValue = default, int maxRetries = 3, int waitSeconds = 5) { lastException = null; for (int retryCount = 0; retryCount <= maxRetries; retryCount++) { try { // 执行传入的业务逻辑 return operation(); } catch (Exception ex) { lastException = ex; // 达到最大重试次数,或当前异常不符合重试规则,终止重试 if (retryCount == maxRetries || !shouldRetry(ex)) { break; } // 等待指定时长后重试 System.Threading.Thread.Sleep(waitSeconds * 1000); } } // 重试全部失败,返回默认值 return defaultValue; }
改造业务函数
去掉业务函数内部的try-catch,让重试逻辑统一处理异常,业务函数仅保留核心逻辑:
public bool PingApi(string apiurl) { // 核心业务逻辑:调用API using (var client = new HttpClient()) { var response = client.GetAsync(apiurl).Result; response.EnsureSuccessStatusCode(); // 触发HTTP错误异常 return true; } }
调用示例(针对网络异常重试)
Exception finalException; bool pingResult = ExecuteWithRetry( // 传入业务逻辑:调用PingApi并传入参数 operation: () => PingApi("https://your-api-url.com"), // 定义重试规则:仅当异常是网络相关异常时重试 shouldRetry: ex => ex is HttpRequestException || ex is System.Net.WebException, out finalException, defaultValue: false, maxRetries: 3, waitSeconds: 5 ); // 处理最终结果 if (!pingResult) { if (finalException != null) { // 记录或处理最终异常 Console.WriteLine($"API调用失败:{finalException.Message}"); } // 执行失败后的 fallback 逻辑 }
关键优势
- 高度灵活:适配任意返回值类型的业务函数,无需修改重试函数即可支持新场景
- 规则自定义:通过
shouldRetry委托精准控制重试触发条件,满足「特定原因异常才重试」的需求 - 避免递归问题:用循环代替原代码的递归实现,防止重试次数过多导致栈溢出
- 逻辑解耦:业务函数专注核心逻辑,重试逻辑统一复用,减少重复代码
内容的提问来源于stack exchange,提问作者Bulo
相关产品推荐
相关产品推荐

