2

我最近读了很多关于这个话题的书,但我仍然需要澄清一些事情

异步方法的整个想法是线程经济

允许许多任务在几个线程上运行。这是通过使用硬件驱动程序来完成这项工作,同时将线程释放回线程池,以便它可以为其他工作提供服务。

请注意 。

不是在谈论与另一个线程相关联的异步委托(与调用者并行执行任务)。

但是,我已经看到了 2 种主要类型的异步方法示例:

  • 仅使用现有I/O 异步操作的代码示例(来自书籍),beginXXX / endXX例如 Stream.BeginRead.
    而且我找不到任何使用现有.net I/O 操作的异步方法 示例,例如 )Stream.BeginRead

  • 像这样(和这个)的代码示例 。这实际上并没有调用异步操作(尽管作者认为他是 - 但他实际上导致线程阻塞!)

问题 :

异步方法是否 仅与 .net I/O 现有方法一起使用,例如BeginXXX , EndXXX

我的意思是,如果我想创建自己的 异步方法 ,例如BeginMyDelay(int ms,...){..} , EndMyDelay(...). 如果没有将阻塞的线程绑定到它,我就无法做到......对吗?

非常感谢你。

ps 请注意这个问题被标记为 .net 4 而不是 .net4.5

4

3 回答 3

1

你在谈论APM。APM 广泛使用操作系统概念,称为IO 完成端口。这就是为什么不同的 IO 操作是使用 APM 的最佳候选者。

您可以编写自己的 APM 方法。但事实上,这些方法要么超越现有的 APM 方法,要么受 IO 限制,并使用一些本机操作系统机制(例如FilesStream,使用重叠文件 IO)。

对于计算绑定的异步操作,APM 只会增加复杂性,IMO。

再澄清一点。

使用硬件的工作本质上是异步的。硬件需要时间来执行请求——newtork 卡必须发送或接收数据,HDD 必须读/写等。如果 IO 是同步的,则生成 IO 请求的线程正在等待响应。APM 在这里提供帮助 - 你不应该等待,只需执行其他操作,当 IO 完成时,我会打电话给你,APM 说。

要点 - 操作在 CPU 之外执行。

当您编写任何计算密集型操作时,它将使用 CPU 执行它而无需任何 IO,这里没有什么可等待的。所以,APM 没有帮助——如果你需要 CPU,你需要线程——你需要线程池。

于 2013-03-23T09:52:49.217 回答
0

我认为,但我不确定,您可以创建自己的异步方法。例如创建一个新线程并等待它完成一些工作(数据库查询,...)。

就整体系统性能而言,它可能没有用,因为您说您只是创建了另一个线程。但是例如,如果您在 IIS 上工作,则在等待“后台”操作时,原始请求线程可以用于其他请求。

我认为 IIS 具有固定数量的线程(线程池),因此在这种情况下可能很有用。

于 2013-03-23T10:09:34.237 回答
0

我的意思是,如果我想创建自己的异步方法,例如 BeginMyDelay(int ms,...){..} ,EndMyDelay(...)。如果没有将阻塞的线程绑定到它,我就无法做到......对吗?

虽然我还没有深入研究异步的实现,但我看不出有什么理由不能做到这一点。

最简单的方法是使用现有的库来帮助 [例如计时器] 或某种事件系统 IIRC。

然而,即使你不想使用任何库助手,你也会遇到一个问题......“阻塞线程”。

当然,代码确实看起来像这样:

while (true){
      foreach (var item in WaitingTasks)
              if (item.Ready())
                 /*fire item, and remove it from tasks*/;

      /*Some blocking action*/
}

事情是-“某些阻止操作”不一定是“阻止”。您可以让线程产生/休眠,或使用它来处理一些数据。例如,Unity 游戏引擎对 Coroutines 做了类似的事情 - 处理所有代码的同一个线程还检查是否需要更新各种协程 [由于时间而延迟]。用 ProcessGameLoop() 替换 /*Some blocking action*/。

有帮助的锄头,请随时提出问题/更正等。

于 2013-03-23T10:53:42.110 回答