我正在尝试使用Task.WhenAll(任务)。等待(超时)等待任务完成并在该进程任务结果之后。
考虑这个例子:
var tasks = new List<Task<Foo>>();
tasks.Add(Task.Run(() => GetData1()));
tasks.Add(Task.Run(() => GetData2()));
Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(5));
var completedTasks = tasks
.Where(t => t.Status == TaskStatus.RanToCompletion)
.Select(t => t.Result)
.ToList();
// Process completed tasks
// ...
private Foo GetData1()
{
Thread.Sleep(TimeSpan.FromSeconds(4));
return new Foo();
}
private Foo GetData2()
{
Thread.Sleep(TimeSpan.FromSeconds(10));
// How can I get the result of this task once it completes?
return new Foo();
}
这些任务之一可能无法在5秒超时内完成执行。
是否有可能以某种方式处理在指定超时后完成的任务的结果?也许在这种情况下我没有使用正确的方法?
修改:
我正在尝试获取在指定超时内完成的所有任务结果。在Task.WhenAll(任务)之后可能会有以下结果。等等(TimeSpan.FromSeconds(5)):
答案 0 :(得分:2)
最后,在删除答案的用户的帮助下,我最终得到了这个解决方案:
private const int TimeoutInSeconds = 5;
private static void Main(string[] args)
{
var tasks = new List<Task>()
{
Task.Run( async() => await Task.Delay(30)),
Task.Run( async() => await Task.Delay(300)),
Task.Run( async() => await Task.Delay(6000)),
Task.Run( async() => await Task.Delay(8000))
};
Task.WhenAll(tasks).Wait(TimeSpan.FromSeconds(TimeoutInSeconds));
var completedTasks = tasks
.Where(t => t.Status == TaskStatus.RanToCompletion).ToList();
var incompleteTasks = tasks
.Where(t => t.Status != TaskStatus.RanToCompletion).ToList();
Task.WhenAll(incompleteTasks)
.ContinueWith(t => { ProcessDelayedTasks(incompleteTasks); });
ProcessCompletedTasks(completedTasks);
Console.ReadKey();
}
private static void ProcessCompletedTasks(IEnumerable<Task> delayedTasks)
{
Console.WriteLine("Processing completed tasks...");
}
private static void ProcessDelayedTasks(IEnumerable<Task> delayedTasks)
{
Console.WriteLine("Processing delayed tasks...");
}
答案 1 :(得分:0)
而不是Waitall,你可能只想做一些5秒的旋转/睡眠,然后在你上面查询列表。
然后,您应该能够在几秒钟之后再次枚举以查看其他内容已完成。
如果需要考虑性能,您可能需要额外的“换行”以查看所有任务是否在5秒之前完成。