繁体   English   中英

在 'async' 方法上到达 'await' 时线程会发生什么?

[英]What happens to the thread when reaching 'await' on 'async' method?

正如标题所暗示的那样,我的问题是关于“异步”和“等待”的背景。

是不是说当前线程到达 'await' 关键字,就进入“睡眠”状态,等待方法完成后唤醒?

谢谢!

盖伊

说当前线程到达'await'关键字是什么,它会进入“休眠”,并在await方法完成时唤醒,这是真的吗?

不。 async的全部意义在于,当他们可以做其他工作时避免让线程处于休眠状态。 另外,如果运行async方法的线程是一个UI线程,那么你真的不希望它在休眠 - 你希望它可用于其他事件。

当执行到达await表达式时,生成的代码将检查您正在等待的事物是否已经可用。 如果是,你可以使用它并继续前进。 否则,它将为“等待”部分添加延续并立即返回

继续确保在等待值准备好时运行异步方法的其余部分。 发生在哪个线程取决于您正在等待的上下文 - 如果异步方法在线程池线程中运行,则延续可以在与该方法启动的线程不同的线程上运行...但是不应该物。 (其余的上下文仍将传播。)

请注意,async方法在没有完成的情况下返回是很好的 - 因为异步方法不能直接返回值 - 它总是返回一个Task<T> (或Task ,或void )...并且返回的任务由只有当异步方法真正到达终点时才会完成方法。

不。当前线程实际上不会进入睡眠状态。 执行继续。 这是它的全部技巧。 您可能有一些代码处理数据,而异步操作仍处于待处理状态。 这意味着当异步完成时,您的主线程可以自由运行并处理其他数据。

至于问题的另一部分 - 异步只是在另一个线程上执行,而不是当前线程。 我相信CLR负责旋转这些线程,因此允许同时执行许多异步操作(即,您可能同时从不同的Web服务器异步检索数据)。

async只是允许使用await关键字的语法糖。

如果在 ASP.NET Core 中使用了async, await ,那么您的请求线程将被释放到线程池中。

正如斯蒂芬·克利里所说:

异步请求处理程序的操作方式不同。 当一个请求进来时,ASP.NET 使用它的一个线程池线程并将它分配给那个请求。 这次请求处理程序将异步调用该外部资源。 这会将请求线程返回到线程池,直到对外部资源的调用返回。 图 3 说明了在请求异步等待外部资源时具有两个线程的线程池。

在此处输入图片说明

重要的区别是请求线程在异步调用过程中已经返回到线程池中。 当线程在线程池中时,它不再与该请求相关联。 这一次,当外部资源调用返回时,ASP.NET 使用其线程池线程之一并将其重新分配给该请求。 该线程继续处理请求。 当请求完成时,该线程再次返回到线程池。 请注意,对于同步处理程序,请求的生命周期使用相同的线程; 相比之下,对于异步处理程序,不同的线程可能会分配给同一个请求(在不同的时间)。

对于桌面应用程序:

await释放当前线程,但不会释放到线程池。 UI 线程不是来自线程池。 如果您运行异步方法,例如ExecuteScalarAsync没有async, await关键字,那么无论如何该方法都将异步运行。 调用线程不会受到影响。

特别感谢Panagiotis Kanavos 的精彩评论。

例如,您有一个繁重的存储过程,并且您的存储过程需要 10 分钟才能执行。 如果您在没有async, await关键字的情况下从 C# 运行此代码,那么您的执行线程将等待您的存储过程 10 分钟。 而这个等待线程什么都不做,它只会等待存储过程。

但是,如果使用async, await关键字,则您的线程将不会等待存储过程。 该线程将有资格工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM