C# 第一个任务完成后如何等待
我试图使用C# 第一个任务完成后如何等待,c#,async-await,C#,Async Await,我试图使用Task.WaitAny来等待一系列任务,但我真正想要的是等待第一个RanToCompletion任务,而不是取消的任务 因此,当我有一堆任务时,其状态如下: 0取消;1取消;2取消;3取消;4取消;5.完成 理想情况下,我希望Task.WaitAny返回5,但它返回的是0 我应该如何等待第一个RANTO完成任务?没有现成的。我们需要编写一些助手方法,如注释中所述 下面是一个使用TaskCompletionSource的实现 public class MyTask { priv
Task.WaitAny
来等待一系列任务,但我真正想要的是等待第一个RanToCompletion
任务,而不是取消的任务
因此,当我有一堆任务时,其状态如下:
0取消;1取消;2取消;3取消;4取消;5.完成代码>
理想情况下,我希望Task.WaitAny
返回5
,但它返回的是0
我应该如何等待第一个RANTO完成任务?没有现成的。我们需要编写一些助手方法,如注释中所述
下面是一个使用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();
}
}
如果5个都失败了怎么办?我的意思是什么都没有完成。你想做什么?^他第一个说要完成,所以他可能有五个以上的任务,只等一个任务完成。@Ronaldstacion我的问题是如果一切都失败了怎么办。5只是从问题中推断出的一个数字。@Sriram Sakthivel因为在这种情况下没有失败,只有取消。@SriramSakthivel假设我们可以返回一些其他数字,比如-1,如果所有任务都已完成,但没有一个任务运行到完成状态?
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