【发布时间】:2014-04-29 04:47:01
【问题描述】:
我有 2 个服务于 WCF 调用。我从客户端向两个服务发送相同的异步 WCF BeginXXX 调用,然后开始等待带有 WaitHandle.WaitAny(waitHandles) 的回复,其中 waitHandles 是来自 2 个 BeginXXX 调用返回的 IAsyncResults 的 WaitHandles 数组。
我只想使用响应速度更快的服务的回复,即当 WaitHandle.WaitAny 返回索引时,我只使用相应的 IAsyncResult 调用 EndXXX 以获得更快的结果。我从不打电话给另一个 EndXXX。
我这样做的原因是,有时服务在垃圾收集中使用了几秒钟,并且无法快速响应。根据我的经验,这两个服务通常在不同的时间进行垃圾收集,所以其中一个几乎总是能够返回一个快速的答案。我的客户端应用程序对时间非常关键,我需要在几毫秒内得到答案。
我的问题是:
我可以安全地忽略为响应速度较慢的其他服务调用 EndXXX 方法吗?我对较慢的结果不感兴趣,但想尽快使用较快的结果。根据我的实验,即使我不为相应的较慢 BeginXXX 异步结果调用 EndXXX 方法,似乎也不会发生任何不好的事情。
如果我没有为相应的 BeginXXX 发出 EndXXX 调用,有人介意向我解释一下究竟会发生什么吗?在 Visual Studio 中的调试器下,我似乎能够看到另一个答案是通过 I/O 完成端口在 .NET 框架中处理的,并且该处理并非源自调用 EndXXX 的客户端。由于没有进行 EndXXX 调用,我似乎没有任何内存泄漏。我认为所有涉及的对象都被垃圾回收了。
服务器端方法 XXX 实现是单个同步 XXX 还是显式异步 BeginXXX/EndXXX 对有什么区别吗?
恕我直言,同步 XXX 方法实现将始终返回一个答案 需要在某个地方处理。它发生在客户端还是服务器上 当我没有打电话给 EndXXX 时,我的情况是怎样的?
使用 WaitHandles 是一种等待最快结果的好方法吗?
如果我必须为我发送的每个 BeginXXX 调用 EndXXX,事情就会变得很尴尬。我将不得不将无趣的 EndXXX 调用委托给另一个线程,该线程只会忽略结果。在我的原始线程中调用所有 EndXXX 调用会破坏以同步方式获取和使用更快答案的目的。
【问题讨论】:
-
您所针对的框架版本是什么?也许您可以使用基于异步
Task的模式,它可以处理EndXXX: stackoverflow.com/a/21498956/1768303 -
AFAIK 基于任务的模式使用线程池来处理其工作。我的客户端每秒会进行数千次调用,并且会完全破坏线程池。
-
我在answer@aku 中解决了您的问题。
标签: c# multithreading performance wcf asynchronous