我可以忽略WCF异步EndXXX调用吗?

aku*_*aku 5 c# performance wcf multithreading asynchronous

我有2个服务WCF调用服务.从客户端我发送相同的异步WCF BeginXXX调用到两个服务,然后开始等待WaitHandle.WaitAny(waitHandles)的回复,其中waitHandles是来自2个BeginXXX调用返回的IAsyncResults的WaitHandles数组.

我想只使用响应速度更快的服务的回复,即当WaitHandle.WaitAny返回索引时,我只使用相应的IAsyncResult调用EndXXX以获得更快的结果.我永远不会打电话给另一个EndXXX.

我这样做的原因是有时服务在垃圾收集中使用几秒钟而且无法快速回答.根据我的经验,这两个服务通常在不同的时间进行垃圾收集,因此其中一个几乎总是能够返回快速答案.我的客户端应用程序非常关键,我需要在几毫秒内得到答案.

我的问题是:

  1. 我可以安全地忽略为响应速度较慢的其他服务调用EndXXX方法吗?我对较慢的结果不感兴趣,但希望尽快使用更快的结果.根据我的实验,即使我没有为相应较慢的BeginXXX异步结果调用EndXXX方法,似乎也没有发生任何不好的事情.

  2. 当我没有为相应的BeginXXX进行EndXXX调用时,有人会介意向我解释究竟发生了什么吗?在Visual Studio中的调试器下,我似乎能够看到通过I/O完成端口在.NET框架中处理另一个答案,并且此处理不是来自我的客户端调用EndXXX.而且由于没有进行EndXXX调用,我似乎没有任何内存泄漏.我假设所涉及的所有对象都是垃圾收集的.

  3. 服务器端方法XXX实现是单个同步XXX还是显式异步BeginXXX/EndXXX对是否有任何区别?

  4. 恕我直言,同步XXX方法实现将始终返回需要在某处处理的答案.当我无法调用EndXXX时,是否会在客户端或服务器端发生?

  5. 使用WaitHandles是一种等待最快结果的好方法吗?

  6. 如果我必须为每个BeginXXX调用EndXXX,我发出的东西很尴尬.我将不得不将无趣的EndXXX调用委托给另一个忽略结果的线程.在原始线程中调用所有EndXXX调用将无法以同步方式获取并使用更快的答案.

usr*_*usr 5

  1. 文档说你必须调用end方法.如果你违反了文档的要求,你就处于未定义的行为领域.资源可能泄漏.也许他们只是在负荷下这样做,谁知道呢?
  2. 我不知道,对不起.我给出了部分答案.我的建议:实现一个什么都不做的服务方法,并在一个循环中调用它10M次.资源泄漏了吗?如果是的话,你有答案.
  3. 不,服务器和客户端是独立的.服务器可以是同步的,客户端可以是异步的,反之亦然.两者都无法区分对方的不同之处.这两个服务由TCP和明确定义的协议分隔.客户端甚至不可能知道服务器的功能.服务器甚至不必使用.NET.
  4. 我不确定你在问什么.在引擎盖下,WCF客户端使用TCP.传入的数据将在"某处"处理(实际上在线程池中).
  5. 如果您的代码基本上是同步的,那么这是您可以做的最好的.您将刻录一个等待N个异步服务调用的线程.没关系.
  6. 你为什么不指定一个回调BeginXXX,除了调用之外EndXXX什么也不做?这样,您始终可以调用EndXXX并遵循框架的使用方式.您仍然可以使用等待句柄.


Pet*_*hie 2

取决于您调用开始/结束模式的对象。有些已知会泄漏。来自 CLR 通过 C# 作者:Jeffrey Richter:

您必须调用Endxxx,否则您将泄漏资源。当您启动异步操作时,CLR 会分配一些内部资源。如果 Endxxx 从未被调用,则只有当进程终止时才会回收这些资源。