如何根据条件等待任务

本文关键字:等待 任务 条件 何根 | 更新日期: 2023-09-27 18:16:35

我想知道从GetDataFromLongRunningOp返回的结果中是否至少有一个满足某个条件:

foreach (var item in list)
{
    var result = GetDataFromLongRunningOp(item);
    if (CheckCondition(result))
    {
        return true;
    }
}
return false;

我如何并行地为每一项调用GetDataFromLongRunningOp,以减少找到答案所需的总时间?

编辑: GetDataFromLongRunningOp是一个异步方法。

如何根据条件等待任务

使用Task.Run异步运行GetDataFromLongRunningOp。使用TaskCompletionSource,当返回满足条件的结果时,它将返回一个已完成的任务。如果没有结果满足条件,那么tcs.Task将永远不会完成。您需要另一个等待所有任务完成的任务。因此,最后,您需要等待tcs.TaskTask.WhenAll完成。

var result = false;
var tasks = new List<Task>();
var tcs = new TaskCompletionSource<bool>();
foreach (var item in list)
{
    var task = Task.Run(() => GetDataFromLongRunningOp(item))
        .ContinueWith(t =>
        {
            if (CheckCondition(t.Result))
            {
                result = true;
                tcs.TrySetResult(true);
            }
        });
    tasks.Add(task);
}
await Task.WhenAny(tcs.Task, Task.WhenAll(tasks));
return result;

假设您的工作是CPU限制而不是IO限制,您可以查看Parallel.ForEach:

Parallel.ForEach(list, (item) => 
{
    var result = GetDataFromLongRunningOp(item);
    if (CheckCondition(result))
    {
        return true;
    }
});
return false;

请注意,您必须确保GetDataFromLongRunningOp是线程安全的,当然,代码进行基准测试,以确保并行运行它不会超过成本。