Task.WhenAny

问题描述 投票:0回答:1

task1
task2
task3
是我在函数开头启动的任务,什么是
await Task.WhenAny(task1,task2,task3);
如果在代码到达该await 语句之前已经完成了多个任务,则返回?是随机任务吗?争论结束后的第一个?已完成的任务列表?

顺便说一句,这并不重要,我只是想知道这是不确定的行为还是有优先级

c# asynchronous async-await task-parallel-library
1个回答
0
投票

让我们从这个超级简单的应用程序开始:

TaskCompletionSource<object> tsc = new();
CancellationTokenSource cts = new(1_000);
cts.Token.Register(() => tsc.SetResult((object)null), useSynchronizationContext: false);
var task1 = tsc.Task;
var task2 = Task.Delay(1_000);
var task3 = Task.Run(async () => { await Task.Delay(1_000); });

var res = await Task.WhenAny(task1, task2, task3);

Console.WriteLine($"Task1: {task1.Id}");
Console.WriteLine($"Task2: {task2.Id}");
Console.WriteLine($"Task3: {task3.Id}");
Console.WriteLine($"res: {res.Id}");

这里我们有三个任务,所有任务都会在一秒钟内完成。如果您多次运行此应用程序,则

res.Id
将是三个任务之一,具体取决于任务调度。


现在,让我们用在到达

Task.WhenAny

之前完成的任务来扩展它
TaskCompletionSource<object> tsc = new();
CancellationTokenSource cts = new(1_000);
cts.Token.Register(() => tsc.SetResult((object)null), useSynchronizationContext: false);
var task1 = tsc.Task;
var task2 = Task.Delay(1_000);
var task3 = Task.Run(async () => { await Task.Delay(1_000); });
var task4 = Task.Run(() => {});
var task5 = Task.Run(() => {});

var res = await Task.WhenAny(task1, task2, task3, task5, task4);

Console.WriteLine($"Task1: {task1.Id}");
Console.WriteLine($"Task2: {task2.Id}");
Console.WriteLine($"Task3: {task3.Id}");
Console.WriteLine($"Task4: {task4.Id}");
Console.WriteLine($"Task5: {task5.Id}");
Console.WriteLine($"res: {res.Id}");

await Task.WhenAny(task1,task2,task3); 是什么意思如果在代码到达该等待语句之前已经完成了多个任务?

在我的实验中,

res.Id
始终是
task4.Id

这是一个随机任务吗?

上面的例子有点偏差。因此,让我们将

task4
task5
更改为
Task.Delay(10);

在这种情况下,
res.Id
将是
task4.Id
task5.Id
,具体取决于日程安排。

争论结束后的第一个?

不,无论您将

task4
添加到
task5
的参数列表中之前还是之后都没有关系。

已完成的任务列表?

不。如果您需要一个简单的 Linq 查询就可以返回该结果

Task.WhenAny

© www.soinside.com 2019 - 2024. All rights reserved.