【问题标题】:Am I deadlocking? Why?我陷入僵局了吗?为什么?
【发布时间】:2010-07-24 02:05:30
【问题描述】:

我有一个 Silverlight 3 应用程序,它需要调用 WCF 服务。 WCF 服务依次调用 ASMX Web 服务。当 WCF 服务调用完成时,silverlight UI 需要更新。

正在异步调用 WCF。

问题是 Silverlight 应用程序需要调用 WCF 方法(后来在内部调用 asmx)数百次。我知道因为它在 aSync 中,所以会产生数百个线程,所以我已经编写了检查代码以确保调用 WCF 函数的时间不超过 X 时间。只有当 1 个呼叫完成时,我才会再添加一个呼叫。我希望这将检查线程总数。 X 值的理想值是多少?我在一个简单的 XP 机器上,有双核 CPU 和 4 GB 内存。

随着 WCF 调用完成,我需要在 silverlight UI 上显示进度条。

这适用于较少数量的调用,但是当我需要进行大约 10000 次调用时,一段时间后我会在 Silverlight 的 WCFCompleted 方法中超时。我觉得我可能会陷入僵局?

我的 WCF 配置为多个并发。

每次 WCF 调用完成时,它都会更新 UI……这会导致这种死锁吗?

有什么想法吗?我被困在这里,迷路了。

【问题讨论】:

  • 所以,如果我需要调用 WCF 10,000 次,我从调用它开始 20 次,当 1 个方法调用完成时,我再添加一个调用,依此类推。
  • 如果您使用的是Delegate.BeginInvoke,它应该会自动使用内置的线程池和任务队列,因此您应该不需要管理并发任务的数量。
  • 我不确定我是否在内部使用 Delegate.BeginInvoke。我刚刚将 WCF 作为服务引用添加到我的 Silverlight 应用程序。使用其自动生成的代理 XXXBegin 和 XXXComplete 回调方法。

标签: wcf multithreading deadlock asynchronous threadpool


【解决方案1】:

只有当一个线程分配资源并等待另一个资源,而另一个线程分配第二个资源并等待第一个资源时,才会导致死锁。谁都不能继续。

问题在于,当多个线程调用 Windows UI 时,它们都不知道 Windows 试图使用的内部资源。无法预测结果可能是什么;死锁是一种可能性。

【讨论】:

    【解决方案2】:

    因此,除非您正在这样做,否则数百个线程不会被启动。异步调用的要点是,在操作完成并发布到完成端口之前,调用已经完成并且什么都不存在(因为什么都不会发生)。这假设您正在使用回调。如果在 IAsyncResult 上调用 EndXXX,线程将阻塞,直到操作完成。

    现在可能会发生一些事情。首先,如果您有一个复杂的服务后端,您的服务中可能会出现死锁。然而,第二个可能更可能是您的 WCF 服务配置需要调整。 WCF 调优是一种魔法,一旦你了解了它,你通常会发誓永远不会再使用 WCF。

    在您的客户端上同时允许多少个出站连接,而在您的服务上同时允许多少个入站连接?在客户端和服务器上使用WCF tracing 通常是您解决这些类型问题所需要的。我建议从那里开始,因为我将使您能够获得所需的详细信息,以了解实际情况。

    【讨论】:

    • 目前我将其限制为 Silverlight 应用程序对异步 WCF 方法的调用不超过 20 次。
    【解决方案3】:

    我怀疑您在这种情况下遇到了线程死锁。 WPF,我也相信 Silverlight,使用线程调度程序将消息从工作线程调度到 UI。这是此类 UI 响应速度如此之快的原因之一。更有可能的是,您正在重载 WCF 终结点堆栈、其缓冲区或 ASP.NET 管道堆栈和/或缓冲区。在处理网络连接时,创建大量连接的速度和频率存在限制。如果您在几分钟内创建了 10,000 个连接,那么您完全有可能超出 TCP 堆栈。当一个套接字关闭时,它不会立即重用,并进入最终等待状态大约 4 分钟。如果您在 4 分钟内触发几批 10,000 个连接,您将消耗所有可用的套接字,从而使 WCF(以及具有保留端口之外的任何其他 Windows 应用程序)无法通信。我不能确定您是否遇到过这种情况(您真的需要使用 lot 的套接字),但我详细回答了另一个关于如何提高默认阈值的问题对于这里的 Windows TCP 堆栈:

    WCF: System.Net.SocketException - Only one usage of each socket address (protocol/network address/port) is normally permitted

    如果您真的想深入了解问题的根源,我建议您启用 WCF 跟踪日志记录。 WCF 跟踪日志捕获大量信息,并提供有关每个连接和处理的消息的极其详细的信息。启用后,您应该能够识别问题,除非它发生在 ASP.NET 管道或 HTTP.sys 中,甚至在到达 WCF 之前。我建议阅读以下文章:

    【讨论】:

      【解决方案4】:

      我后来似乎通过以下方式解决了这个问题: 1) 将 asmx 服务转换为 WCF 2) WCF 超时时间从 1 分钟增加到 5 分钟 3) 我现在不是在每个 Completed 回调上更新 UI 进度条,而是使用一个计时器,它只说每 30 秒更新一次 UI。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-14
        • 2021-10-12
        • 2017-08-12
        • 1970-01-01
        相关资源
        最近更新 更多