有没有办法触发 2 个任务,等待一个完成(不取消另一个任务),然后在返回结果之前设置一个时间

Is there a way to trigger 2 tasks, await for one to complete (without cancelling the other task) and then set a time before returning result

我正在现有应用程序中实现一项新功能,想知道如何最好地实现以下目标:

  1. 创建两个任务。
  2. 并行启动它们。
  3. 等待并等待其中之一完成。
  4. 其中一个完成后,在 return 响应之前将计时器旋转 t 秒。这样做是因为其中一项任务可能 运行 比另一项任务执行的时间更长。

我有#1 到#3 但#4 的解决方案。

List<Task> tasks = new List<Task>(length);
tasks.Add(CreateTask(get_data_source));
await Task.WhenAny(tasks);

我不想在 #3 中提供任何超时。但我想等到任务完成,然后触发一个计时器 t 秒。 t 秒后,return 结果(如果两者都完成,则其他都只是完成的任务)。

这可能是 Task.WhenAll() 的好地方。当所有任务完成时,它将 return。这样您就可以等待所有任务响应,而不是等待一段时间。

https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=netframework-4.8

第一个任务完成后,您可以等待任何剩余任务或延迟任务完成。

这将使您有可能等待 5 秒以完成其他任务,如果没有,则 return 结果。

var tasks = new List<Task>
{
    CreateTask(get_data_source),
    CreateTask(get_data_source2)
};

var completedTask = await Task.WhenAny(tasks);

await Task.WhenAny(Task.WhenAll(tasks), Task.Delay(5000));

// Return result

另一个例子,使用 CancellationToken and CancellationTokenSource.CancelAfter

var ts = new CancellationTokenSource();

var list = Enumerable.Range(0, 4)
                     .Select(x => DoStuff(ts.Token))
                     .ToList();

await Task.WhenAny(list);

ts.CancelAfter(1000);

await Task.WhenAll(list);

如果您的任务正在使用CancellationTokens帮助关闭它们优雅

,这将有所帮助