我希望在设置超时时间的同时启动多个任务。我的想法是收集在规定时间内完成的任务结果,并取消(或者忽略)其他任务。
我尝试使用这里所解释的WithCancellation扩展方法,但是抛出异常导致WhenAll返回并且没有提供任何结果。
以下是我尝试过的内容,但我也愿意接受其他方向的建议(请注意,由于需要在任务中使用httpContext,因此我需要使用await而不是Task.Run):
我尝试使用这里所解释的WithCancellation扩展方法,但是抛出异常导致WhenAll返回并且没有提供任何结果。
以下是我尝试过的内容,但我也愿意接受其他方向的建议(请注意,由于需要在任务中使用httpContext,因此我需要使用await而不是Task.Run):
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
IEnumerable<Task<MyResults>> tasks =
from url in urls
select taskAsync(url).WithCancellation(cts.Token);
Task<MyResults>[] excutedTasks = null;
MyResults[] res = null;
try
{
// Execute the query and start the searches:
excutedTasks = tasks.ToArray();
res = await Task.WhenAll(excutedTasks);
}
catch (Exception exc)
{
if (excutedTasks != null)
{
foreach (Task<MyResults> faulted in excutedTasks.Where(t => t.IsFaulted))
{
// work with faulted and faulted.Exception
}
}
}
// work with res
编辑: 根据@Servy下面的答案,这是我采用的实现方法:
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(3));
IEnumerable<Task<MyResults>> tasks =
from url in urls
select taskAsync(url).WithCancellation(cts.Token);
// Execute the query and start the searches:
Task<MyResults>[] excutedTasks = tasks.ToArray();
try
{
await Task.WhenAll(excutedTasks);
}
catch (OperationCanceledException)
{
// Do nothing - we expect this if a timeout has occurred
}
IEnumerable<Task<MyResults>> completedTasks = excutedTasks.Where(t => t.Status == TaskStatus.RanToCompletion);
var results = new List<MyResults>();
completedTasks.ForEach(async t => results.Add(await t));
taskAsync
是做什么用的? - NeddySpaghetti