假设ASP.NET WebAPI请求到达控制器方法。
假设请求代表需要处理的“事件”。该事件具有与之关联的多个操作,应该并行执行。例如,每个操作可能需要调用其他服务器上的特定REST端点,这些端口是I / O绑定操作,应尽快启动,不应等待一个返回,然后再启动下一个操作。
实现此模式的最正确/ performant方法是什么?
我已经读过使用Task.Run是个坏主意,因为它只是抓取了额外的ThreadPool线程,让主请求线程空闲/阻塞。虽然如果我正在运行单个任务,这是有道理的,但我不确定在这种情况下是否适用这些建议。
例如,如果事件有4个需要完成的操作(每个操作可能有多个自己的I / O绑定调用),我会在循环中调用Task.Run 4次来初始化每个操作,然后等待使用Task.WaitAll
生成任务。
Q1: 在等待Task.WaitAll返回时,主请求线程是否会返回到ThreadPool供另一个请求使用,或者只是占用主线程而使其空闲直到Task.WaitAll完成?
Q2:如果它占用主线程,是否可以通过使用async
关键字标记控制器方法并使用await Task.WhenAll
调用来解决?我想成像这会在等待时将主线程返回到池中,从而允许它用于其他请求或事件操作。
问题3:由于Task.Run
将可能在I / O绑定调用上阻止的工作项排队,如果所有操作都使用async
实现,性能会提高并在基于任务的异步I / O方法上使用await
调用?
关于使用Task.Run进行事件操作的整个方法,目标只是尽快启动所有操作的I / O绑定调用。我想如果(如在Q3中)所有操作都是async
方法,我可以让它们全部在循环中的主请求线程上启动,但我不确定这会比使用单独的任务启动它们更好.Run电话。也许有一种我完全不同的方法,我不知道。