在没有处理异步操作时,异步操作在哪里等待?

时间:2014-05-09 05:47:31

标签: .net asynchronous task-parallel-library async-await

如果我在C#(任务)中启动一组异步操作,每个从Web下载一些内容,然后我使用Task.WhenAny()处理第一个可用的任务结果,其他异步操作"等待"而主线程处理结果?

我只能假设操作系统级别存在某种内部队列,它存储状态以及后台发生的下载结果。

我的问题是,此队列位于何处,此队列是否存在任何尚未处理的异步操作结果的危险?

1 个答案:

答案 0 :(得分:5)

TPL Task Schedulers跟踪通过Task.RunTask.Factory.StartNewTask.ContinueWithTask.RunTask.RunSynchronously启动的任务。

对于promise样式的任务(使用TaskCompletionSource创建的任务),引用由I / O完成回调或事件处理程序保存。 Stephen Cleary有great blog post与此类任务相关。

对于编译器生成的状态机任务(由async方法返回的任务,其中包含await语句),任务在任何“内部”任务(或{{{{{{它等待的是“飞行中”。在这种情况下,继续回调由任务等待者保持(例如,TaskAwaiter)。此编译器生成的回调包含对环境(“外部”)任务的强烈间接引用。当“内部”任务完成时,将通过SynchronizationContext.PostTaskScheduler.Current任务调度程序调度回调(如果在await处没有捕获同步上下文)。

如果是自定义等待者,custom awaiter强制保留传递给await的{​​{1}}延续回调,以防止环境任务被垃圾收集,而“ - 飞行”。

  

我的问题是,此队列位于何处并且存在任何危险   这个队列溢出了异步操作的结果   哪些尚未处理?

如果任务排队的速度快于完成,那么从长远来看,最终可能会耗尽内存。这是排队论处理的一个常见问题,它不是TPL任务特有的东西。