如何等待有条件的任务? [英] How to wait tasks with conditions?

查看:106
本文介绍了如何等待有条件的任务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些任务,其中返回布尔。我只是想等待,当所有任务返回True首先,直到。是否可以 ?

I have some tasks which return a bool. I just want wait until when any task returns True firstly. is it possible ?

我的第一个想法是使用一个CancellationTokenSource但由于它抛出,当我称之为Task.WaitAll方法的异常,这不是一个好主意。

My first idea was to use a CancellationTokenSource but it was not a good idea because of it throws an exception when I call the Task.WaitAll method.

第二个选择是使用布尔我通过参考,如果这是真的,直接返回。它的工作原理,但它不是高性能的:

The second option is to use a bool I pass in reference and if it's true, return directly. it works but it's not performant :

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

Task.WaitAll(new Task[] { t0, t1, t2, t3, t4 });
return t0.Result | t1.Result | t2.Result | t3.Result | t4.Result;

和的方法:

 private static bool Find(int[,] m1, int[,] m2, ref bool isFound)
 {
      if (isFound)
           return false;

      // Do work...
 }



编辑

EDIT :

作为答案preconized,我使用了一个 TaskCompletionSource<布尔> 现在:

As the answer preconized, I use a TaskCompletionSource<bool> now :

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;

在此情况下,当所有任务返回假的,没有什么是注意到了,这是正常的。不过,我不知道如何使用 WhenAll 方法。我想补充一点:

In this case, when all tasks return false, nothing is noticed and it's normal. However I don't know how to use the WhenAll method. I tried to add this :

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

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



但它不工作:(

But it does not work :(

推荐答案

一种选择是创建一个 TaskCompletionSource 任何你想要的类型(标识结果,如果这是必需的)。然后加入延续到每个任务,调用 TaskCompletionSource.TrySetResult 如果结果是真实的。

One option would be to create a TaskCompletionSource of whatever type you want (to identify the result, if that's required). Then add a continuation to each of the tasks, calling TaskCompletionSource.TrySetResult if the result is true.

然后就等着上的 TaskCompletionSource.Task ,它避免你不必调用 Task.WaitAny 多次,检查结果等。

Then just wait on the TaskCompletionSource.Task. It avoids you having to call Task.WaitAny repeatedly, checking for results etc.

所有的任务已返回false棘手位已经注意到..在.NET 4.5,这将是相当容易,由通过的 Task.WhenAll - 那么你只是等待第一个<$ C $的c> {成功,都以失败告终} 来完成。

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 - then you'd just wait for the first of { success, all failed } to complete.

这篇关于如何等待有条件的任务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆