如果我在C#(任务)中启动一组异步操作,则每个操作都会从Web上下载一些内容,然后使用Task.WhenAny()处理第一个可用的Task结果,其他异步操作将在主线程执行时“等待”处理结果?
我只能假设操作系统级别上存在某种内部队列,该队列存储状态以及在后台进行的下载结果。
我的问题是,此队列位于何处,并且该队列是否有尚未处理的异步操作结果溢出的危险?
TPL任务调度跟踪这些任务开始通过Task.Run
,Task.Factory.StartNew
,Task.ContinueWith
,Task.Run
或Task.RunSynchronously
。
对于诺言式的任务(使用创建的任务TaskCompletionSource
),引用由I / O完成回调或事件处理程序保留。Stephen Cleary在与此类任务相关的博客文章中非常出色。
对于编译器生成的状态机任务(那些由内部async
带有await
语句的方法返回的任务),只要它正在等待的任何“内部”任务(或自定义等待者)处于“运行中”状态,该任务就会保持活动状态。在这种情况下,继续回调由任务等待者(例如TaskAwaiter
)保留。该编译器生成的回调对环境(“外部”)任务具有很强的间接引用。当“内部”任务完成时,将通过SynchronizationContext.Post
或TaskScheduler.Current
任务调度程序来调度回调(如果在时未捕获到同步上下文await
)。
如果使用自定义的等待者,则可能需要牢记await
传递给的继续回调INotifyCompletion.OnCompleted
,以防止环境任务在“进行中”时被垃圾回收。
我的问题是,此队列位于何处,并且该队列是否有尚未处理的异步操作结果溢出的危险?
如果任务排队的速度比完成任务的速度快,从长远来看,您最终可能会耗尽内存。排队论是一个普遍的问题,并不是TPL任务特有的。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句