What happens to the thread when reaching 'await' on 'async' method?
如标题所示,我的问题是关于"异步"和"等待"的背景。
如果说当前线程达到了"wait"关键字,那么它会进入"sleep",当等待方法完成后会醒来吗?
谢谢!
家伙
- 虽然我认为这可能会引起一个很好的讨论,但答案应该和谷歌async await一样简单。实际上,您可以得到:msdn.microsoft.com/en-us/library/hh156528.aspx。
- C异步CTP中的awaiting线程可能会发生什么复制?
Is it true to say that what the current thread reaches 'await' keyword, it goes to"sleep", and wakes up when the await method is done?
不,async的关键是避免线程在执行其他工作时休眠。另外,如果运行async方法的线程是一个UI线程,那么您真的不希望它处于休眠状态—您希望它对其他事件可用。
当执行达到await表达式时,生成的代码将检查您等待的内容是否已经可用。如果是,你可以用它继续前进。否则,它将在"等待"部分添加一个延续,并立即返回。
continue确保在可等待的值准备就绪时运行异步方法的其余部分。在哪个线程中发生取决于您等待的上下文-如果异步方法在线程池线程中运行,则继续可以在与方法启动的线程不同的线程上运行…但这不重要。(上下文的其余部分仍将被传播。)
请注意,异步方法在未完成的情况下返回是可以的-因为异步方法不能直接返回值-它总是返回Task(或Task或void)。方法返回的任务只有在异步方法真正到达末尾时才能完成。
- 我本来要回答的,但我太晚了。:)我认为这是来自msdn:An await expression does not block the thread on which it is executing. Instead, it causes the compiler to sign up the rest of the async method as a continuation on the awaited task. Control then returns to the caller of the async method. When the task completes, it invokes its continuation, and execution of the async method resumes where it left off.的一个很好的解释。
- @博伯恩:我喜欢这样,除了它意味着你总是在等待一项任务:)
- 有两件事让我困惑。一个是我们有一个要调用的方法,它是等待(返回任务)的参数,另一个是任务的延续(方法的其余部分)。所以这两个都将在同步上下文中运行,或者其中一个(或者两者)被给予特殊处理?
- @bsk:首先运行以获得可等待的部分没有任何特殊处理——它只是一个产生值的表达式。尽管假定只有在同步上下文中才运行延续,但如果您已经在同步上下文中,则不能在没有同步上下文的情况下运行后者。但问题不在于它被给予特殊的处理,而在于当前正在执行的线程的同步上下文是什么。
- 根据我的理解,在回答"方法返回的任务只有在异步方法真正到达末尾时才能完成"中的这一行,任务在我们等待的事情完成后立即完成,异步中的其余代码作为回调运行(因为我们为任务提供了continueWith())。如果我错了,请纠正我。
- @你错了。方法返回的任务点是这样调用代码就可以知道整个异步方法何时完成。当第一个等待的操作完成时,为什么调用代码会在意呢?这只是一个实现细节。
- 我认为这会导致死锁。以调用异步方法的UI线程为例,我们知道在等待之后的方法的其余部分需要在UI线程上执行(由于同步上下文),但是正如您所说的,调用线程(此处为UI线程)只有在异步中的所有代码都完成之后才会得到通知,然后H只有等待完成时(不是所有代码都是异步完成的),UI线程才能在等待完成后返回并执行代码吗?
- @BSK:您需要区分调用线程和调用代码。设想方法A调用异步方法B,它调用异步方法C和D。从B返回到A的任务只有在整个B完成时才会完成,这大概只有在C和D返回的任务完成时才会发生。我建议你做进一步的研究和实验,如果你仍然困惑的话,用一个具体的例子问一个新问题,而不是继续这里。
- 当然。但是我做了很多研究,仍然有这些类型的问题。我认为你是对的。是时候提出新问题了:)
不,当前线程实际上没有进入睡眠状态。继续执行。这就是它的全部诀窍。您可能有一些代码在异步操作仍挂起时处理数据。这意味着当这些异步完成时,您的主线程可以自由运行和处理其他数据。
至于问题的另一部分-异步只是在另一个线程上执行,而不是当前线程。我相信clr负责旋转这些线程,以便同时允许许多异步操作(即,您可能同时从不同的Web服务器异步检索数据)。