【问题标题】:Does an asynchronous call require an extra thread in the current process or use another thread in a thread pool?异步调用是否需要当前进程中的额外线程或使用线程池中的另一个线程?
【发布时间】:2010-09-17 09:14:55
【问题描述】:

我指的是this 答案,它说它不是必需的,但几乎没有具体的假设。这个问题很笼统。

  • 我正在使用 C#
  • 异步进程什么都不做,只是调用外部 API 并等待回复。

【问题讨论】:

  • 你能在你的外部 API 的接口上发布一些信息吗?答案取决于此。 “调用外部 API 并等待回复”听起来是同步的,所以澄清一下会很有帮助。
  • 您可以忽略“等待回复”。我的意思是我们没有在同一进程/同一系统中进行任何其他操作(高资源消耗硬盘或复杂计算)。

标签: c# .net multithreading asynchronous threadpool


【解决方案1】:

通常是的,但我至少能想到一个例外。要启动异步操作,您必须将操作转移到调用者的上下文之外。我的意思是调用者不应该阻塞等待操作完成。这通常意味着操作必须转移到新创建的线程、来自ThreadPool 的线程、IO 完成端口、另一个进程等。

我说我想到了一个例外。如果我们稍微歪曲我们对异步的定义,我们可以允许发起者不会阻塞等待操作完成而不实际将操作移动到另一个线程的场景。最好的例子是 UI 消息泵。在 .NET 中,很容易从 UI 线程本身调用 Control.BeginInvoke 以在同一线程上发布委托的执行。发起者显然不会阻塞等待委托完成,但委托最终会开始在同一个线程上执行。这绝对是我们通常认为的异步术语的曲解,因为在这种情况下,操作会阻塞,直到调用者完成,而不是相反。

【讨论】:

  • 如果您有建议的例外情况,或者如果我以外的任何人都可以投票,您能否为您建议的例外情况提供参考。
  • @Ismail:Control.BeginInvoke 的 MSDN 文档几乎准确地说明了这一点。它甚至提到您可以从托管控件的相同线程调用BeginInvoke,并且委托将在那个线程上“异步”执行。
  • 我该如何做类似的事情(即不启动新线程)来调用外部 Web 服务?
  • @Ismail:不可能。异步调用 Web 服务的机制没有消息循环,因此不会遇到我描述为唯一异常的问题。
【解决方案2】:

你的问题太笼统了。 Windows API 在不使用线程的情况下对异步 I/O 有特定的支持,例如查看 ReadFile() 的文档。 lpOverlapped 参数控制这一点。 ReadFileEx() 函数允许指定 I/O 完成回调。 .NET 框架类很好地涵盖了这一点。

此机制不涵盖调用慢速外部 API 函数,您需要启动自己的线程。

【讨论】:

    【解决方案3】:

    是的,使用了池线程。但是该线程并没有等待外部设备。当 I/O 完成时,线程被重用并调用一个(另一个)线程。

    请参阅 MSDN 上的 I/O Asynchronous Completion

    【讨论】:

      猜你喜欢
      • 2016-09-26
      • 1970-01-01
      • 1970-01-01
      • 2021-06-16
      • 2017-06-20
      • 2017-08-14
      • 2011-11-23
      • 2023-03-18
      • 2010-12-22
      相关资源
      最近更新 更多