【问题标题】:Synchronization problems with Monitor class in WCF serviceWCF 服务中的 Monitor 类的同步问题
【发布时间】:2009-12-30 10:17:28
【问题描述】:

我有一个自托管的 WCF 服务,但遇到以下问题:创建服务实例 15 分钟后,操作合同方法中的 TryEnter 调用不断返回 false,但 Main 函数中的 TryEnter 调用,它也使用通过 Monitor 类同步,返回 true。

这是我的应用程序和错误的描述: 我正在 Windows XP SP2 中的 Visual Studio 2008 (C#) 中开发自托管 WCF 服务。 主机的 ServiceHost 实例是在 Main 函数的开头创建的。 Main 函数运行一个 while (true) 循环,在此期间它执行定期读取、写入、维护等。 有一个对象的静态集合(可以随着时间的推移添加或删除),它们充当工作线程的容器。其中一些线程执行 Main 函数请求的定期工作,而其他线程则执行对远程设备的按需读取和写入。使用 Monitor 类(TryEnter 和 Exit 方法)对这些对象进行同步锁定。这些对象也可以通过使用相同功能的服务合同方法(服务)进行访问。在 Main 函数和服务方法之间进行同步。创建服务实例后,它会以设计性能运行整整 15 分钟,之后从服务发出的每个 TryEnter(obj, timeout) 调用在指定的超时到期后都返回 false。然而,这不会影响在 Main 函数中进行的 TryEnter 调用,即它们总是返回 true。 我尝试更改 InstanceContextMode、ConcurrencyMode 的设置以及服务限制属性 maxConcurrentCalls="1" ; maxConcurrentSessions="5" 并且每种配置都产生了相同的效果。当我重新启动主机应用程序时,服务再次响应,但当我在应用程序运行时强行关闭并重新打开主机时(服务实例保留在内存中),服务不再响应。 这不是服务不可用的情况,因为调用永远不会到达服务实例。该方法被调用,它的执行是在该方法的关键部分之前的 TryEnter 调用,并且 TryEnter 在超时(15 秒)后返回 false。 我已经检查并仔细检查了 TryEnter 和 Exit 的配对——这些方法总是在临界区结束时释放锁。 即使在 15 分钟期限结束后,其他不使用锁定或相关对象的合约操作也能正常工作。

提前谢谢大家。 节日快乐!

【问题讨论】:

    标签: c# wcf timeout monitor self-hosting


    【解决方案1】:

    Monitor 是可重入的,所以听起来你的Main 方法的线程未能释放锁。因此,当它请求锁 (TryEnter) 时,它会获得锁(将计数器增加 另一个 1)。

    所有其他线程都将被拒绝。您将需要调试获取和持有锁的位置。

    我已经检查并再次检查了 TryEnter 和 Exit 的配对——这些方法总是在临界区结束时释放锁

    抱歉,但我认为你要进行三重检查。特别是,与lock 不同,TryEnter 不会有任何特殊的异常处理。您的代码应如下所示:

    if(Monitor.TryEnter(lockObj, timeout)) {
        try {
            ...
        } finally {
            Monitor.Exit(lockObj);
        }
    }
    

    另外 - 确保您永远不要在代码中重新签名 lockObj,因为这不会解锁正确的对象。

    (或类似的使用标志,尤其是在 .NET 4.0 中,there are new overloads 代表 Enter 等)

    【讨论】:

      猜你喜欢
      • 2020-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多