c# - C# .NET CORE:如果返回某种结果,则取消其他任务
问题描述
如果其中一项返回错误(布尔)结果,如何取消所有任务?是否可以确定哪个任务返回了结果?
class Program
{
private static Random _rnd = new Random();
static void Main(string[] args)
{
var tasksCounter = _rnd.Next(4, 7);
var cts = new CancellationTokenSource();
var tasks = new Task<bool>[tasksCounter];
for (int i = 0; i < tasks.Length; i++)
{
tasks[i] = CreateTask(cts);
}
Console.WriteLine("Waiting..");
Task.WaitAny(tasks);
Console.WriteLine("Done!");
Console.ReadKey();
}
private static Task<bool> CreateTask(CancellationTokenSource cts)
{
return Task.Factory.StartNew(TaskAction, cts.Token).Unwrap();
}
private static async Task<bool> TaskAction()
{
var delay = _rnd.Next(2, 5);
await Task.Delay(delay * 1000);
var taskResult = _rnd.Next(10) < 4;
return await Task.FromResult(taskResult);
}
}
我尝试使用 Task.WaitAll、Task.WaitAny 等,但这些方法都没有提供有用的(在我的情况下)功能。
解决方案
编辑:
正如@ckuri 在评论中所说,利用现有属性Task
而不是编写自定义结果类会更容易。相应地调整了我的答案。
一种解决方案是检查CreateTask()
方法中的结果并将 a 传递给CancellationToken
您的TaskAction()
方法:
private static Task<bool> CreateTask(CancellationTokenSource cts)
{
return Task.Run(async () =>
{
var result = await TaskAction(cts.Token);
// If result is false, cancel all tasks
if (!result)
cts.Cancel();
return result;
});
}
private static async Task<bool> TaskAction(CancellationToken token)
{
// Check for cancellation
token.ThrowIfCancellationRequested();
var delay = Rnd.Next(2, 5);
// Pass the cancellation token to Task.Delay()
await Task.Delay(delay * 1000, token);
var taskResult = Rnd.Next(10) < 4;
// Check for cancellation
token.ThrowIfCancellationRequested();
return taskResult;
}
现在你可以在你的方法中做这样的事情Main
来接收所有没有被取消的任务:
try
{
// Wait for all tasks inside a try catch block because `WhenAll` throws a `AggregationException`
// containing a `TaskCanceledException`, if the token gets canceled
await Task.WhenAll(tasks);
}
catch { }
var tasksWithResult = tasks.Where(t => !t.IsCanceled).ToList();
推荐阅读
- javascript - 如何在反应中更改日期格式?
- sql - SQL。比较当前行的值与上一行的相同比较结果的值
- reactjs - 如何在codepen中运行使用“create-react-app”创建的反应项目?
- java - 方法 count(JobViewWrapper) 已经定义
- google-fonts - 为什么只加载三种谷歌字体中的一种?
- allure - 在诱惑报告中,无法看到放在 @Step 注释方法中的记录器语句
- vue.js - 如何从状态 vuex 映射对象中的数组?
- c++ - 如何创建一个大小为 NxN 的方形二维数组,其中 N 由用户提供并填充一定范围内的随机数?
- html - 身体标签的背景图片不可见
- assembly - 汇编中数据段变量的绝对地址是什么?