.net 当使用;异步;方法是否阻止了线程池的线程?

.net 当使用;异步;方法是否阻止了线程池的线程?,.net,threadpool,.net,Threadpool,好吧,下面是事实: 长时间阻塞线程池的线程不是一个好主意(因为它们是有限的)。 任务使用线程池的线程,因此用于短期而不是长期阻塞操作。 异步方法(如实体框架中的FindAsync)返回一个任务,您可以等待(或等待)以接收结果 我不明白的是: 如果我调用FindAsync(例如FindAsync),是否只创建了一个在线程池线程上运行并调用非异步查找方法的任务(在查找返回之前阻塞线程池线程)?或者是否涉及更深层次的操作系统机制,并且在Find方法返回之前未使用线程池线程 原因是: 如果变量1为tru

好吧,下面是事实:

长时间阻塞线程池的线程不是一个好主意(因为它们是有限的)。 任务使用线程池的线程,因此用于短期而不是长期阻塞操作。 异步方法(如实体框架中的FindAsync)返回一个任务,您可以等待(或等待)以接收结果

我不明白的是:

如果我调用FindAsync(例如FindAsync),是否只创建了一个在线程池线程上运行并调用非异步查找方法的任务(在查找返回之前阻塞线程池线程)?或者是否涉及更深层次的操作系统机制,并且在Find方法返回之前未使用线程池线程

原因是:

如果变量1为true,则调用FindAsync方法或自己启动任务与调用其中的Find方法之间没有区别

如果变量2为true,则存在差异,因为启动调用Find方法的任务将长期阻塞线程池线程,而调用FindAsync则不会

长时间阻塞线程池的线程不是一个好主意(因为它们是有限的)

线程池将通过注入一个新线程来响应线程的“丢失”,因此长时间阻塞线程池线程并不是特别有问题。(当然,最好不要首先阻塞线程池线程)

任务使用线程池的线程,因此用于短期而不是长期阻塞操作

这仅适用于调度到线程池的委托任务。关于任务的许多旧(.NET 4-era)文档都假定您正在使用线程池中调度的委托任务,因此这通常是对任务的误解

在现代世界,委派任务要难得多;如今,承诺任务更为常见。承诺任务只是一个“信号”,意思是“完成了一些事情”。有关委托任务和承诺任务的更多信息,请参阅我在和上的博客文章

(此外,可以将委托任务调度到任何类型的
任务调度器
;它们不仅仅用于线程池任务)

异步方法(如实体框架中的FindAsync)返回一个任务,您可以等待(或等待)以接收结果

这里需要对使用
async
实现的方法和以
*async
结尾并用于
wait
的方法进行区分。这两者通常一起,但并不总是

async
始终返回承诺任务,而不是委托任务。另外,通常预期
*Async
方法将返回承诺任务,但有些方法会返回委托任务。当方法执行此操作时,我称之为“伪异步”,因为它只是同步阻塞另一个线程

如果我调用FindAsync(例如FindAsync),是否只创建了一个在线程池线程上运行并调用非异步查找方法的任务(在查找返回之前阻塞线程池线程)

一般情况下不是这样。几乎所有由.NET返回承诺任务提供的
*Async
方法

或者是否涉及更深层次的操作系统机制,并且在Find方法返回之前未使用线程池线程

正如我在文章中所描述的那样,大多数.NET
*Async
方法返回的Promise任务在后台使用I/O完成端口

如果变量1为true,则调用FindAsync方法或自己启动任务与调用其中的Find方法之间没有区别

如果变量2为true,则存在差异,因为启动调用Find方法的任务将长期阻塞线程池线程,而调用FindAsync则不会

在一般情况下,您希望使用
*Async
方法,这样可以避免阻塞任何线程

然而,正如其他人在评论中指出的那样,实体框架的这个特定示例稍微复杂一些。实体框架本身是异步不可知的;它建立在“提供者”之上,后者可能支持也可能不支持异步。Microsoft的SqlClient提供程序确实支持异步,因此
FindAsync
与SQL Server对话将正常异步工作。但是,其他提供程序可能不支持(在撰写本文时,SQLite是不支持异步的常见提供程序),对于这些提供程序,“异步”API(如
FindAsync
)实际上是通过阻塞线程池线程来实现的

因此,在一般情况下,“变体2”是正确的;但是对于您的
FindAsync
的特定示例,它们都是正确的

长时间阻塞线程池的线程不是一个好主意(因为它们是有限的)

线程池将通过注入一个新线程来响应线程的“丢失”,因此长时间阻塞线程池线程并不是特别有问题。(当然,最好不要首先阻塞线程池线程)

任务使用线程池的线程,因此用于短期而不是长期阻塞操作

这仅适用于调度到线程池的委托任务。关于任务的许多旧(.NET 4-era)文档都假定您正在使用线程池中调度的委托任务,因此这通常是对任务的误解

在现代世界,委派任务要难得多;如今,承诺任务更为常见。承诺任务只是一个“信号”,意思是“完成了一些事情”。有关委托任务和承诺任务的更多信息,请参阅我在和上的博客文章

(此外,可以将委托任务调度到任何类型的
任务调度器
;它们不仅仅用于线程池任务)

异步方法(如实体框架中的FindAsync)返回一个任务,您可以等待(或等待)以接收结果