繁体   English   中英

线程,任务,异步/等待,线程池

[英]Threads, Task, async/await, Threadpool

我在这里对多线程感到非常困惑:(我正在阅读关于C#Async / Await关键字。我经常读到,通过使用这个异步功能,代码被执行“非阻塞”。人们将代码示例分为两类“ IO-Bound“和”CPU绑定“ - 我执行io-bound时我不应该使用线程,因为该线程只会等待..

我不明白......如果我不想让用户等待操作,我必须在另一个线程上执行该操作,对吧?

如果我使用Threadpool,一个“Thread”-class,delegate.BeginInvoke或TPL的实例 - 每个异步执行都在另一个线程上完成。 (有或没有回调)

您缺少的是并非每个异步操作都在另一个线程上完成。 等待IO操作或Web服务调用不需要创建线程。 在Windows上,这是通过使用OS I / O完成端口完成的

当你调用Stream.ReadAsync东西时,操作系统会向磁盘发出一个读命令,然后返回给调用者。 磁盘完成读取后,会通知操作系统内核,然后操作系统将触发回调进程。 所以没有必要创建一个新的线程池线程,它只会坐下来阻塞。

这是什么意思:

假设您从数据库(在另一台服务器上)查询某些数据 - 您将发送请求并等待答案。 而不是有一个线程阻塞并等待返回,最好注册一个在数据返回时调用的回调 - 这是(或多或少)async / await的作用。 它将释放线程做其他事情(将其返回到池中)但是一旦您的数据异步返回它将获得另一个线程并在您离开位置继续您的代码(它实际上是某种处理该状态的状态机) )。

如果你的计算真的是CPU密集型(让我们说你正在计算素数)事情是不同的 - 你不是在等待一些外部IO,你在CPU上做了很多工作 - 这里最好使用一个线程,这样你的用户界面不会阻止。

我不明白......如果我不想让用户等待操作,我必须在另一个线程上执行该操作,对吧?

不完全是。 不管怎样,手术都需要很长时间。 当您拥有单用户应用程序时,在单独的线程上运行长时间运行的东西可以让用户界面保持响应。 至少这允许UI具有类似“取消”按钮的东西,其可以接受用户输入并取消对另一个线程的处理。 对于某些单用户应用程序,允许用户在长时间运行的任务完成时继续执行其他操作(例如,让他们在另一个文件上载或下载时处理一个文件)是有意义的。

对于Web应用程序,您不希望在冗长(ish)IO期间阻塞线程池中的线程,例如在从数据库读取或调用其他Web服务时。 这是因为线程池中只有有限数量的线程可用,如果它们全部在使用中,则Web服务器将无法接受其他HTTP请求。

暂无
暂无

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

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