为什么我的BeginInvoke同步运行

时间:2015-08-26 01:19:54

标签: c# multithreading wcf asynchronous begininvoke

我已经创建了一个WCF应用程序,并且我在多个地方使用BeginInvoke来异步运行方法。在某些地方它是异步的,而在其他地方它是同步运行的。因为系统非常复杂,所以我希望抛出这个高级问题,希望有人知道BeginInvoke会被迫同步运行的原因。

我考虑并相信的可能原因不是原因:

  • 我用尽了ThreadPool线程 - 我认为在峰值时我使用的线程少于20个。
  • 我在这些线程上使用锁定来停止它们的并发执行 - 没有采用同步,因为每次调用都是在单独的WCF ServiceHost上的方法
  • 父异步方法(肯定是异步运行)调用许多子BeginInvokes,你不能嵌套异步调用 - 我不认为这是一个限制
  • 父异步方法本身是WCF ServiceHost的一部分,它是InstanceContextMode.PerSession,并且嵌套异步调用有一些限制 - 再次,我不这么认为,但是FYI
  • 每个被调用的子节点是(与父节点不同)WCF ServiceHost,我调用的方法是相同ServiceType的实例,并作为InstanceContextMode.Single和ConcurrencyMode.Single运行。 - 这是否会以某种方式影响调用例程以异步方式运行它们(我不明白为什么会这样,但为了以防万一)

非常感谢任何想法/解决方案

1 个答案:

答案 0 :(得分:2)

我想在他的“Windows上的并发编程”一书中引用Joe Duffy关于Delegate.BeginInvoke的引用:

  

按照惯例,所有委托类型都提供BeginInvoke和EndInvoke方法以及普通的同步Invoke方法。虽然这是一个很好的编程模型功能,但您应该尽可能远离它们。该实现使用远程处理基础结构,这对异步调用施加了相当大的开销。直接对线程池进行队列工作通常是一种更好的方法,但这意味着您必须自己协调集合点逻辑。

之前我已经完成了自己的测试,经常使用这些测试时,开销可能会达到很多秒。也许这不是你问题的答案 - 因为在没有看到和调试代码的情况下,我认为几乎是不可能的。这是一个建议,你应该再看看你的方法。也许是通过直接将工作排队到ThreadPool,或者使用TPL(任务' s / async& await)。

如果您仍然在寻找当前代码的问题,而不是为了更好的策略而修改它,并且您仍然需要帮助,那么您应该找到一种方法来重现您的症状(它是同步运行的)并提供证明这一点的代码。