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



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

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

我的问题是,这个队列位于哪里,这个队列是否有溢出的危险与尚未处理的异步操作的结果?

TPL任务调度程序跟踪通过Task.Run, Task.Factory.StartNew, Task.ContinueWith, Task.RunTask.RunSynchronously启动的任务。

对于承诺类型的任务(使用TaskCompletionSource创建的任务),引用由I/O完成回调或事件处理程序保存。Stephen Cleary有一篇关于这类任务的很棒的博客文章。

对于编译器生成的状态机任务(由内部有await语句的async方法返回的任务),只要它等待的任何"内部"任务(或自定义侍者)处于"运行中",该任务就保持活动状态。在这种情况下,延续回调由任务等待器(例如,TaskAwaiter)保存。这个编译器生成的回调包含对环境("外部")任务的强间接引用。当"内部"任务完成时,回调将通过SynchronizationContext.PostTaskScheduler.Current任务调度器调度(如果在await点没有捕获同步上下文)。

对于自定义侍者,可能需要对传递给INotifyCompletion.OnCompletedawait延续回调进行严格控制,以防止环境任务在"飞行中"被垃圾收集。

我的问题是,这个队列在哪里,有危险吗这个队列由于异步操作的结果而溢出哪些还没有处理?

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

最新更新