【发布时间】:2017-06-20 19:04:21
【问题描述】:
AFAIK 以下是正确的:
长时间阻塞线程池的一个线程并不是一个好主意(因为它们是有限的)。 任务使用线程池的线程,因此是短期的,而不是长期的阻塞操作。 异步方法(如 Entity Framework 中的 FindAsync)返回一个您可以等待(或等待)以接收结果的任务。
我不明白的:
如果我打电话给例如FindAsync 是否只是创建了一个在 ThreadPool 线程上运行并调用非异步 find 方法的任务(阻塞 ThreadPool 线程直到 find 返回)?或者是否涉及更深层次的操作系统机制,并且在 Find 方法返回之前没有使用 ThreadPool 线程?
原因:
如果变体 1 成立,则调用 FindAsync 方法或自己启动任务与在其中调用 Find 方法没有区别。
如果变体 2 成立,则存在差异,因为启动一个调用 Find 方法的任务将长期阻塞一个 ThreadPool 线程,而调用 FindAsync 则不会。
【问题讨论】:
-
Stephen Cleary 写了一篇精彩的文章There Is No Thread,您可能想读一读。请记住
TaskCompletionSource的存在——它的存在是为了允许创建绝对不在线程池上运行的Tasks。 -
在这种特定情况下,下面的 SqlClient 提供真正的异步执行,而不使用后台线程。 IO(包括网络调用)在 Windows 中本质上是异步的。线程阻塞是模拟的。 ADO.NET 使用 IO 完成端口与数据库服务器通信,并在收到响应后恢复处理。其他提供者(例如 MySQL 的)通过启动一个新线程来伪造异步
标签: .net threadpool