【问题标题】:Async WCF call to save thread?异步 WCF 调用以保存线程?
【发布时间】:2013-11-15 13:26:33
【问题描述】:

another SO question 中,有人建议我发送异步网络请求,而不是在后台线程上发送同步请求。原因是为了不浪费一个线程。我正试图了解这是怎么回事。

这是最初的方法。我可以理解这里有两个线程。一个是主线程 (1),一个是进行 WCF 调用的后台线程 (Task.Run) (2):

这是我对建议方法的草图。我试图了解如何保存线程。在异步 WCF 调用之后,不会为异步 WCF 调用的回调创建另一个线程吗?

再想一想,如果不需要回调处理,也许只使用一个线程?

【问题讨论】:

  • 你在写什么样的客户端应用?
  • @JonSkeet 这是一个 WPF 客户端。
  • 在异步网络调用中,没有线程正在运行进行调用。 (您的 UI 线程保持运行,照常处理 UI 消息)

标签: c# wpf wcf asynchronous async-await


【解决方案1】:

在您的 WPF 客户端中,您的客户端中可能有一个 OnClick,检查客户端是否被点击的线程在哪里?

操作系统本身的答案是检查点击,然后将消息传递给消息泵,该消息泵反过来调用您的函数。 WCF 函数的回调是这样的,操作系统本身正在监听回复消息,当它收到回复消息时,它会发送一个信号,在线程池中找到一个空闲线程并在那时执行回调。

同步持有线程和让回调方法最后生成线程的主要区别在于线程池是一个池。当线程池中的线程完成其工作时,它不会被销毁,它会等待一段时间,看看是否有更多工作可以完成,它将被重用做这项新工作。

所以两个选择是

  • 有 1 个线程坐在那里等待没有其他工作等待函数解除阻塞(同步 + 线程)
  • 当操作系统告诉我们我们在哪里等待的信息已经出现时,重用已经完成工作的现有线程(或者如果没有等待并且我们低于ThreadPool.GetMaxThreads(),则生成一个新线程),给它简短处理回调的任务,然后让线程回到池中,以便在其他回调进入时为它们做其他工作。

【讨论】:

  • 好的,我想我现在明白了。仍然使用两个线程,只是在后台线程上的同步请求中,该线程正在等待 WCF 同步调用完成。在异步 WCF 调用中,没有等待。听起来对吗?
  • 正确。在同步版本中,你在 ThreadPool 中绑定了一个线程(如果你没有指定一个 Task 是 LongRunning 它使用一个线程池线程),它除了用完 ThreadPool 中的一个线程等待一个回复。通过使用异步方法,它可以让线程在池中空闲,直到响应返回。 (注意,并非所有异步方法都使用 ThreadPool 线程,它只是处理回调的常用方式)
  • 这正是我所需要的。谢谢,斯科特!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-01
  • 1970-01-01
  • 2012-10-03
  • 1970-01-01
  • 2012-12-10
  • 1970-01-01
相关资源
最近更新 更多