.net中的异步方法(!)澄清?

时间:2013-03-23 09:46:23

标签: c# multithreading asynchronous .net-4.0

我最近一直在阅读很多关于这个主题的文章,但我还需要澄清一些事情

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

  

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

请注意。

谈论异步委托,它绑定另一个线程(与调用者并行执行任务)。

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

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

  • 代码示例,如this(和this)。实际上并没有调用异步操作(虽然作者认为他是 - 但他实际上导致一个线程阻止!)

问题:

异步方法是否仅用于BeginXXX , EndXXX等.net I / O现有方法?

我的意思是,如果我想创建自己的异步方法,如BeginMyDelay(int ms,...){..} , EndMyDelay(...)。如果没有绑定一个被阻止的线程,我无法完成它....对吗?

非常感谢。

P.S。请注意,此问题被标记为.net 4而不是.net4.5

3 个答案:

答案 0 :(得分:1)

你在谈论APM。 APM广泛使用OS概念,称为IO Completion ports。这就是为什么不同的IO操作是使用APM的最佳候选者。

您可以编写自己的APM方法。 但是,事实上,这些方法将是现有的APM方法,或者它们将受IO限制,并将使用一些本机操作系统机制(如FilesStream,它使用重叠文件IO)。

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

更多澄清。

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

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

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

答案 1 :(得分:0)

我想,但我不确定,您可以创建自己的异步方法。例如,创建一个新线程并等待它完成一些工作(db query,...)。

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

我认为IIS有固定数量的线程(线程池),所以在这种情况下可能会有用。

答案 2 :(得分: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()替换/ *一些阻止操作* /。

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