C# 如何确保无异常抛出的Task执行完成?有什么更优实现方案?
现有实现问题分析
- 语法错误:
Task.Run(async () => await DoSomething();缺少lambda闭合的右括号,代码无法直接通过编译。 - 核心逻辑不满足需求:Task的
IsCompleted属性在任务执行成功、抛出异常失败、被取消三种场景下都会返回true,原代码只要任务进入任意完成状态就会终止循环,没有判断任务是否执行成功。 - 存在并发泄漏风险:你没有等待
DoSomething返回的Task执行完成,就直接等待300ms后判断状态,若DoSomething执行耗时超过300ms,会重复创建新的任务实例,最终导致大量任务并行执行,占用系统资源。 - 冗余包装:
DoSomething本身已经返回Task,不需要用Task.Run额外包裹异步委托,徒增不必要的性能开销。
最优实现方案
首先明确判断DoSomething执行成功的默认依据为Task的IsCompletedSuccessfully属性为true,如果业务中成功与否需要通过其他自定义状态判断,替换示例中的判断条件即可。
基础实现
while (true) { var task = DoSomething(); await task; if (task.IsCompletedSuccessfully) { break; } await Task.Delay(300); }
通用可复用扩展实现
建议封装为通用方法,同时增加最大重试次数限制,避免任务永久失败导致程序死锁:
public static async Task RetryUntilSuccessAsync(Func<Task> taskFactory, int maxRetryCount = int.MaxValue, int retryDelayMs = 300) { if (taskFactory == null) throw new ArgumentNullException(nameof(taskFactory)); if (maxRetryCount < 0) throw new ArgumentOutOfRangeException(nameof(maxRetryCount)); int retryCount = 0; while (retryCount < maxRetryCount) { var task = taskFactory(); await task; if (task.IsCompletedSuccessfully) { return; } retryCount++; await Task.Delay(retryDelayMs); } // 超过最大重试次数可根据业务需求调整为返回错误状态 throw new InvalidOperationException("已达到最大重试次数,任务仍未执行成功"); } // 调用方式 await RetryUntilSuccessAsync(DoSomething);
内容的提问来源于stack exchange,提问作者Nava
相关产品推荐
相关产品推荐

