【问题标题】:APM Pattern Use a Thread from Threadpool?APM 模式使用来自 Threadpool 的线程?
【发布时间】:2013-08-27 16:48:43
【问题描述】:

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

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

【问题讨论】:

  • 如何通过在 .NET 运行时使用 ILSpy 并检查源代码自行查找?

标签: c# multithreading asynchronous


【解决方案1】:

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

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

MessageQueue、FileStream、PipeStream、Socket、FileSystemWatcher、IpcChannel 和 SerialPort 支持。

【讨论】:

  • 是的,我说的是针对 I/O 绑定计算的现有 APM 调用。直到 ThreadPool.BingHandle() 的语句在当前线程上执行,对吗?这就是为什么,它不是立即非阻塞的。非常感谢。
【解决方案2】:

BeginXxx 在当前线程上执行。您可以使用例如轻松地自己验证这一点。反射器。此外,有时回调也在当前线程上执行。一种情况是早期发生错误,另一种情况是实际的异步 I/O 操作阻塞——这种情况有时会发生,如 asynchronous I/O is not guaranteed not to block

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      许多操作使用IO completion ports

      这意味着在等待操作时不使用线程。操作完成后,将在线程池线程上调用回调或使用其他一些同步上下文。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-09
        • 1970-01-01
        • 2010-10-14
        • 1970-01-01
        • 2010-10-02
        相关资源
        最近更新 更多