我有一些任务返回一个布尔值。我只想等到任何任务首先返回True时。可能吗 ?如何用条件等待任务?
我的第一个想法是使用CancellationTokenSource,但它不是一个好主意,因为它在我调用Task.WaitAll方法时引发异常。
第二个选择是使用bool我传入参考,如果它是真的,直接返回。它的工作原理,但它不是高性能:
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...
}
编辑:
的答案preconized,我用一个TaskCompletionSource<bool>
现在:
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;
在这种情况下,当所有任务返回false时,什么都不会被察觉,这是正常的。但是我不知道如何使用WhenAll
方法。我想补充一点:
tcs.Task.Wait();
Task tr = Task.WhenAll(new Task[] { t0, t1, t2, t3, t4 });
if (tr.IsCompleted)
return false;
else
return tcs.Task.Result;
但它不工作:(
难道你不想使用WaitAny而不是WaitAll吗?请参阅http://msdn.microsoft.com/en-us/library/dd270672.aspx – dash 2012-08-06 08:26:56