仅等待一个任务完成
本文关键字:一个 任务 等待 | 更新日期: 2023-09-27 18:37:26
假设我有两个任务,有以下要求:
- 两者都是异步的。
- 两者并行运行
- 其中一个完成的那一刻,我需要知道是哪一个完成了。
我想出了以下代码,但它只是在两个任务启动后挂起(WaitAny 函数永远不会返回)。 我在运行函数下也有一条波浪线,告诉我在其中添加 await,但是当我尝试在 Task.WaitAny 前面添加它时,VS 抱怨。 我应该将 WaitAny 包装在另一个任务中吗? 我做错了什么?
async void Run()
{
Task task1 = Task1();
Task task2 = Task2();
int completedTaskIdx = Task.WaitAny(task1, task2);
Debug.WriteLine("completedTaskIdx = {0}", completedTaskIdx.ToString());
}
async Task Task1()
{
Debug.WriteLine("Task 1 Start");
await Task.Delay(5000);
Debug.WriteLine("Task 1 Stop");
}
async Task Task2()
{
Debug.WriteLine("Task 2 Start");
await Task.Delay(10000);
Debug.WriteLine("Task 2 Stop");
}
使用 asnyc/await 时不要阻塞 UI 线程,会导致 dedlocks。您的WaitAny()
会导致您陷入僵局。请改用WhenAny
,您可以使用Array.IndexOf(
将返回的任务转换回索引。
async Task Run()
{
Task task1 = Task1();
Task task2 = Task2();
var tasks = new[] {task1, task2};
Task completedTask = await Task.WhenAny(tasks);
//It is a good idea to await the retuned task, this is the point a execption would
//be raised if the task finished with a exception.
await completedTask;
int completedTaskIdx = Array.IndexOf(tasks, completedTask);
//.ToString() will cause you to have a bug, you are calling the
//wrong overload of WriteLine. The correct overload will call .ToString() for you.
Debug.WriteLine("completedTaskIdx = {0}", completedTaskIdx);
}
我还修复了您的Debug.WriteLine(
调用中的一个错误,当您想要此重载时,您在哪里调用此重载。我还用async Task
替换了您的async void
,除非您使用它来匹配事件处理程序签名,否则您永远不应该执行asnyc void
。