Task.ContinueWith()间歇性抛出TaskCancelledException及替代方案咨询
不使用ContinueWith的异步处理方案
直接用async/await替代ContinueWith是更简洁且安全的方案,既能完成需求,又能避免间歇性的TaskCancelledException问题。
替代代码
var orgTasks = _options.TierRoutes .Select(async route => { // 等待异步方法完成 var organizations = await _ascendClient.FindAllOrganizations( new OrganizationSearchRequestModel { BaseAddress = route.BaseAddress }); Console.WriteLine($"Completed request for {route.BaseAddress}"); // 更新每个组织的TierName属性 foreach (var organizationDetail in organizations) { organizationDetail.TierName = route.Name; } return organizations; }); // 等待所有任务完成 var result = await Task.WhenAll(orgTasks);
方案优势
async/await会自动处理任务的完成、取消与异常传播,无需手动操作Task对象,从根源避免了ContinueWith中可能出现的取消异常处理疏漏。- 代码逻辑更直观易读,减少了嵌套层级。
- 自动适配上下文调度,避免
ContinueWith中可能出现的调度器配置问题。
可选异常处理
如果需要显式处理取消或其他异常,可以添加try/catch块:
var orgTasks = _options.TierRoutes .Select(async route => { try { var organizations = await _ascendClient.FindAllOrganizations( new OrganizationSearchRequestModel { BaseAddress = route.BaseAddress }); Console.WriteLine($"Completed request for {route.BaseAddress}"); foreach (var organizationDetail in organizations) { organizationDetail.TierName = route.Name; } return organizations; } catch (TaskCanceledException ex) { Console.WriteLine($"Request for {route.BaseAddress} was cancelled: {ex.Message}"); return Enumerable.Empty<OrganizationDetail>(); // 返回空列表或按需处理 } }); var result = await Task.WhenAll(orgTasks);
内容的提问来源于stack exchange,提问作者Vinit Divekar
相关产品推荐
相关产品推荐

