c# - 如何正确使用 Task.WhenAll

标签 c# task async-await

跟随 this question (及其答案)我想使用 TaskCompletionSource 和 Task.WhenAll 等待任何任务首先返回 True 。所以我写了这个:

TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
Task<bool> t0 = Task.Factory.StartNew<bool>(() => Find(paramA, paramB);
Task<bool> t1 = Task.Factory.StartNew<bool>(() => Find(paramC, paramD);
Task<bool> t2 = Task.Factory.StartNew<bool>(() => Find(paramE, paramF);
Task<bool> t3 = Task.Factory.StartNew<bool>(() => Find(paramG, paramH);

t0.ContinueWith(_ =>
{
    if (t0.Result)
        tcs.TrySetResult(t0.Result);
});

t1.ContinueWith(_ =>
{
    if (t1.Result)
        tcs.TrySetResult(t1.Result);
});

t2.ContinueWith(_ =>
{
    if (t2.Result)
        tcs.TrySetResult(t2.Result);
});

t3.ContinueWith(_ =>
{
    if (t3.Result)
        tcs.TrySetResult(t3.Result);
});

t4.ContinueWith(_ =>
{
    if (t4.Result)
        tcs.TrySetResult(t4.Result);
});

tcs.Task.Wait();
return tcs.Task.Result;

当任何任务返回 true 时,它工作正常,但是,正如在之前的答案中所注意到的:

The tricky bit is noticing when all tasks have returned false... in .NET 4.5 this would be reasonably easy, by creating another task via Task.WhenAll

所以我尝试使用 Task.WhenAll 但我不想正确使用它...
我试过类似的东西:

tcs.Task.Wait(); // stays block here when all tasks return false
Task tr = Task.WhenAll(new Task[] { t0, t1, t2, t3, t4 });

if (tr.IsCompleted)
   return false;
else
return tcs.Task.Result;

谢谢你的帮助

最佳答案

您想等到两个任务中的一个完成,那就是Task.WaitAny()用于:

Task tr = Task.WhenAll(new Task[] { t0, t1, t2, t3, t4 });
Task.WaitAny(tcs.Task, tr);

if (tcs.Task.IsCompleted)
    return tcs.Task.Result;

return false;

这也修复了代码中的竞争条件:tr.IsCompleted 可能是 true,即使某些任务返回 true,因为所有的任务可以同时完成。

作为替代方案,您可以使用 Task.WhenAny() ,如果你不想阻止。

但由于您使用的是 .Net 4.5,您最好将 awaitInterleaved() method, which orders the tasks as they complete 一起使用:

async Task<bool> AnyTrue(IEnumerable<Task<bool>> tasks)
{
    foreach(var bucket in Interleaved(tasks))
    {
        if (await await bucket)
            return true;
    }

    return false;
}

关于c# - 如何正确使用 Task.WhenAll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11841230/

相关文章:

c# - "The ConnectionString property is invalid."当我知道它是有效的

eclipse - Mylyn Eclipse TODO 集成

c# - 依赖注入(inject)的 UserManager 正在处理异步调用 (ASP.NET CORE)

javascript - 类型错误 : "FunctionName" is not a function during async and await

c# - WebAPI - 统一来自 ApiController 和 OAuthAuthorizationServerProvider 的错误消息格式

c# - 从图表中仅获取环形节点

c# - 在 Controller 的 MVC **外部**中模拟 HttpContext

gradle - 为什么在 Gradle 中使用 'tasks' 任务时看不到所有任务?

java - 在 Java 中安排重复任务而不让它们因未经检查的异常而停止

c# - 在没有等待的情况下使用异步?