APM模式使用线程池中的线程

本文关键字:线程 模式 APM | 更新日期: 2023-09-27 18:29:11

我想知道.net API中的现有I/O绑定APM调用(BeginGetResponse、BeginRead等)是使用线程池中的线程,还是使用当前线程直到回调。我知道它是"异步"的,一直到硬件/网卡。我还知道回调是在线程池上执行的。我的问题是:BeginGetResponse的所有内容都在Threadpool上执行,或者直到等待I/O的内容都在当前线程上执行;则其余部分在线程池上执行。

我希望问题是清楚的。我真的很想知道BeginGetResponse是如何在幕后实现的。

APM模式使用线程池中的线程

APM是一种更通用的机制。但是您所讨论的案例使用了操作系统对I/O完成端口的支持。一般的想法是,您的主线程调用BeginXxx()方法。在后台,它调用ThreadPool.BindHandle(),设置管道以使端口在I/O操作完成时自动启动TP线程。该线程调用您的回调方法。

核心思想是当I/O操作发生时,没有线程在等待。

MessageQueue、FileStream、PipeStream、Socket、FileSystemWatcher、IpcChannel和SerialPort都支持此功能。

BeginXxx在当前线程上执行。您可以使用Reflector等工具轻松验证这一点。此外,有时回调也在当前线程上执行。一种情况是错误提前发生,另一种情况则是实际的异步I/O操作阻塞时——这种情况有时会发生,因为异步I/O不能保证不阻塞。

使用工作池线程的IAsyncResult方法仅适用于某些任务。像FileIO(不是目录枚举),LDAP查询(v2.0),ADO.net查询。如果您拥有它并且能够承受复杂性,请使用APM。它们通常是由.net人员构建的,因为它需要一些复杂性。否则,如果你认为你会获得速度,就使用手工制作。使用显式线程可以提供更多的控制。具体来说,您可以选择使用前台线程,这将在主线程从main返回后使您的应用程序保持"活动"状态。显式线程还可以指定其COM线程单元。一般规则是,当您有一个工作项队列要做时,使用线程池,当您对它们有体系结构需求时,使用显式线程。

许多操作都使用IO完成端口。

这意味着在等待操作时不使用任何线程。一旦操作完成,就会在线程池线程上或使用其他同步上下文调用回调。