沒有開箱即用的東西。我們需要編寫一些輔助方法,如評論中所述。
這是一個使用TaskCompletionSource
的實現。
public class MyTask
{
private readonly TaskCompletionSource<Task> completionSource = new TaskCompletionSource<Task>();
private readonly Task[] tasks;
private int numberOfTasks;
private MyTask(Task[] tasks)
{
if (tasks.Length == 0)
{
throw new ArgumentException("No tasks");
}
this.tasks = tasks;
this.numberOfTasks= tasks.Length;
}
private int WaitAnyInternal()
{
foreach (var task in tasks)
{
task.ContinueWith(task1 => completionSource.TrySetResult(task1), TaskContinuationOptions.OnlyOnRanToCompletion);
}
foreach (var task in tasks)
{
task.ContinueWith(task1 =>
{
if (Interlocked.Decrement(ref numberOfTasks) == 0)
{
completionSource.SetCanceled();
}
}, TaskContinuationOptions.NotOnRanToCompletion);
}
try
{
completionSource.Task.Wait();
}
catch (AggregateException ex)
{
if (ex.Flatten().InnerExceptions.OfType<OperationCanceledException>().Any())
{
return -1;
}
}
return Array.IndexOf(tasks, completionSource.Task.Result);
}
public static int WaitAnyRanToCompletion(params Task[] tasks)
{
return new MyTask(tasks).WaitAnyInternal();
}
}
然後用它作爲:
var task1 = Task.Run(() =>
{
Thread.Sleep(1000);
throw new Exception();
});//Faulted task
var task2 = Task.Run(() =>
{
Thread.Sleep(5000);
});//Will complete first
var task3 = Task.Delay(10000);//Will complete, but not first
int index = MyTask.WaitAnyRanToCompletion(task1, task2, task3);
//Index will be 1, which means task2
如果所有的5失敗?我的意思是什麼都沒有完成。你想幹什麼? – 2014-11-06 07:44:34
^ 他表示第一個完成rantcompletion,所以他可能有超過五個,只是等待一個任務完成。 – DevEstacion 2014-11-06 07:45:30
@RonaldEstacion我的問題是如果一切都失敗了。 5只是一個從問題推斷的數字。 – 2014-11-06 07:46:32