简体   繁体   English

有没有一种方法可以触发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

I am implementing a new feature in already existing application and would like to know how best I can achieve the following: 我正在现有的应用程序中实现一项新功能,并且想知道如何才能最好地实现以下目标:

  1. Create two tasks. 创建两个任务。
  2. Start them in parallel. 并行启动它们。
  3. Await and wait for one of them to complete. 等待并等待其中之一完成。
  4. Once one of them completes, spun a timer for t seconds before returning the response. 一旦其中一个完成,请在返回响应之前旋转计时器t秒钟。 This is done because one of the task might run for a longer time than another. 这样做是因为一个任务可能比另一个任务运行更长的时间。

I have the solution of #1 to #3 but #4. 我有#1至#3但#4的解决方案。

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

I don't want to provide any timeout in #3. 我不想在#3中提供任何超时。 But I would like to wait till the completion of a task and then trigger a timer for t seconds. 但我想等到任务完成后再触发计时器t秒钟。 After t seconds, return the result (if both completed, then both else just the completed task). t秒后,返回结果(如果两个都完成,则其他两个都只是完成的任务)。

After first task complete, you can await for any of remaining tasks or delay task to complete . 在第一个任务完成后,您可以等待任何剩余任务或延迟任务完成。

This will give you possibility to await 5 seconds for other tasks to complete, if not, then return result. 这将使您有可能等待5秒钟,其他任务才能完成,否则请返回结果。

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

This might be a good place for Task.WhenAll(). 对于Task.WhenAll(),这可能是个好地方。 It will return when all of the tasks are completed. 当所有任务完成时,它将返回。 That way you can just wait for all of the tasks to respond instead of just waiting for an amount of time. 这样,您可以等待所有任务响应,而不必等待一段时间。

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

Another example, using a CancellationToken and CancellationTokenSource.CancelAfter 另一个示例,使用CancellationTokenCancellationTokenSource.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);

This will help if your tasks are using CancellationTokens to help shut them down gracefully 这将有助于如果你的任务是使用CancellationTokens帮助关闭它们勇退

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM