【发布时间】:2013-03-05 20:29:20
【问题描述】:
考虑一个 Microsoft .NET Framework 应用程序,它充分利用 async/await 工具来生成许多同时(或嵌套)任务。没有显着的“流”控制,即任务大多是独立的,不会相互等待完成,因此都在竞争执行。
决定如何/何时调度或执行任务以及在哪个线程上执行任务的框架组件是什么?
有哪些可能的课程可以通过用户代码影响该机制?
编辑
我found 一个很好的句子指出了我的问题的目标:
每当代码等待一个等待者说它尚未完成的等待对象时(即等待者的 IsCompleted 返回 false),该方法需要暂停 ...
这里描述的时间点比我的问题晚了一步 - 有些东西已经处理了用户代码,构造了 awaitable 和 awaiter,可能捕获了上下文并决定哪个线程将执行(或正在执行)该任务。我在问那个“东西”。
我确实看到了用户代码如何影响框架采用的路线,但这些都是程序员的外部“受过教育”决定。假设我们采取了我们可以影响的每一条可能的路线并使其过度饱和......我们正在努力打击一些设施,对吗?也许没有一句话的答案......如果我在下面@Stephen 的回答中看到它的速度很慢,我很抱歉 - 感谢您的帮助并继续挖掘。
(一些相关主题似乎在同步/等待抽象下更深入,如线程池、上下文。我应该朝那个方向挖掘吗?)
结束编辑
自定义 TaskScheduler 是(最佳)(唯一)答案吗?
就问题而言,我忽略了任何外部限制因素,例如资源匮乏(网络、I/O 饱和)或业务原因(人为限制)。或者通过尝试跟踪正在执行的内容等来破解用户代码节流。
【问题讨论】:
-
TaskShedulers 对于限制asyncTasks 几乎没有用(除非您只想限制非异步部分)。您能否详细解释一下您要做什么以及为什么要限制Tasks? -
@svick,我将用户代码视为产生任务(运行它们的请求)的泵。框架中的某些东西正在做出“我将在同一个线程上运行此任务,因为...”或“我将生成一个线程,因为...”的决定。如果你发现我的想法有缺陷——这就是我想要解决的问题——我正在努力学习——少想象,多了解。
-
关于您的编辑:每个
async方法都开始同步执行;它只有在遇到第一个await(其中!IsCompleted)时才变为异步。因此,要安排方法的第一部分,只需使用TaskFactory和自定义TaskScheduler。 -
听起来您真正想要的是一些介绍性的
async材料。我建议阅读(按顺序):my intro、MSDN overview、TAP document 和 FAQ。 -
@Stephen - 感谢关于“RE:您的编辑”评论 - 所以引擎盖下的“事情”,即“第一个
await是 TaskFactory 实现?你能归零吗?在特定方法或方法类上?
标签: .net async-await