我有一个List<Task<bool>>
我想并行枚举的任务,找到要完成的第一个任务,结果是true
不等待或观察任何其他仍待处理的任务的异常。
var tasks = new List<Task<bool>>
{
Task.Delay(2000).ContinueWith(x => false),
Task.Delay(0).ContinueWith(x => true),
};
我曾尝试使用 PLINQ 执行以下操作:
var task = tasks.AsParallel().FirstOrDefault(t => t.Result);
它并行执行,但一旦找到令人满意的结果就不会返回。因为访问 Result 属性是阻塞的。为了让它使用 PLINQ 工作,我必须写下这个令人敬畏的声明:
var cts = new CancellationTokenSource();
var task = tasks.AsParallel()
.FirstOrDefault(t =>
{
try
{
t.Wait(cts.Token);
if (t.Result)
{
cts.Cancel();
}
return t.Result;
}
catch (OperationCanceledException)
{
return false;
}
} );
我编写了一个扩展方法,可以在完成任务时生成任务。
public static class Exts
{
public static IEnumerable<Task<T>> InCompletionOrder<T>(this IEnumerable<Task<T>> source)
{
var tasks = source.ToList();
while (tasks.Any())
{
var t = Task.WhenAny(tasks);
yield return t.Result;
tasks.Remove(t.Result);
}
}
}
// and run like so
var task = tasks.InCompletionOrder().FirstOrDefault(t => t.Result);
但感觉这很常见,有更好的方法。建议?