0

我正在开发 C#/directx 游戏客户端到 Java 的端口,这样我就可以学习一些 C#(因为我完全亵渎了它),同时提高了我对 java opengl 引擎的了解。

当我遇到以下情况时:

Monitor.Enter(preloadDictionary);
try {
     foreach (PreloadEntry entry in preloadDictionary.Values) {
         if (entry.loaded) continue;
         return entry;
     }
} finally {
     Monitor.Exit(preloadDictionary);
}

我可以假设它如下所示吗?

syncronized(preloadDictionary) {
     [...]
}

在以下情况下:

Monitor.Enter(worldServerMap);
try {
     worldServerMap[rv.WorldName] = entry;
     Monitor.PulseAll(worldServerMap);
} finally {
     Monitor.Exit(worldServerMap);
}

是否PulseAll()notifyAll()唤醒所有等待资源的线程一样?(但我在代码中找不到任何Monitor.Wait()被调用的地方)。

4

1 回答 1

2

lock(x) 在最后是 Monitor.Enter 然后 Monitor.Exit。这是一种语言快捷方式。

如果你问我,它是 C# 语言中较弱的部分之一 - 仅仅是因为虽然有 MINOTIR 时它很好,但现在有各种版本的监视器(slim、spinlock 等)并且 lock 只支持其中之一他们。这很方便,但我不确定它是否明智;)

额外的 PulseAll() 是否像 notifyAll() 一样唤醒所有等待资源的线程?(但我在代码中找不到调用 Monitor.Wait() 的任何地方)。

除非您有明确的等待,否则 PulseAll 几乎没有意义,可能来自其他不想进入的线程。Enter 获取不到锁就等待,所以 Exit 足以进行正常同步。

我会开始寻找 Wait 或其他东西 - MOnitor 上的 PulseAll 仅在您有线程等待而不尝试在此阶段进入时才有意义。它可能导致一个糟糕的设计问题,基本上让他们等待然后得到脉冲然后尝试进入,它可能是某些 dsort 的非阻塞设计的一部分 - 很难说,但这是不寻常的。除非您可以在代码中的某处找到等待,否则我可能会尝试杀死 PulseAll 并看看会发生什么。

于 2012-06-03T18:02:06.023 回答