【问题标题】:2 threads entering a locked block of code at the same time2个线程同时进入锁定的代码块
【发布时间】:2015-02-06 18:28:40
【问题描述】:

我试图一次只允许一个线程进入某个代码块:

private static object lockObject = new object();

protected override void WndProc(ref Message message) {
    if (id != null) {
        id.ProcessMessage(message);

        lock(lockObject) {
            if (id.ScanCode.Length > 4) {
                ...
            }
        }
    }

    base.WndProc(ref message);
}

有时有 2 个线程进入其中并执行代码。我已经在 VS 调试器中确认了这一点。有时只有 1 个线程进入,这很好,但至少有一半的时间,2 个线程进入 - 似乎永远不会超过 2 个。

在 if 块中我正在这样做:

id.ScanCode = string.Empty;
return;

对我来说,这似乎应该阻止第二个线程进入,如果它确实被阻塞了。但也许我做错了。防止第二个线程进入那里的最简单方法是什么?他们可以同时进入吗?

【问题讨论】:

  • 我怀疑这是怎么发生的。你已经使用了 Lock() 两个线程无法在 lock 语句中输入代码
  • 要么是调试器撒谎,要么是你错误地解释了你看到的内容
  • 他很可能误解了调试器的输出。
  • 这似乎是一个窗口进程。任何窗口都属于一个特定线程,因此不能是多个线程进入此代码。如果您使用 Invoke 或类似工具,它可能看起来就是这样。
  • @SweatCoder 可以显示调试器的屏幕截图,您可以在其中看到两个线程?

标签: c# multithreading c#-4.0


【解决方案1】:

锁定不会阻止任何数量的线程进入该块。它只是延迟它们直到它被释放。它只会向您保证一次只有一个线程会进入该代码块。一旦第一个线程存在,第二个线程就会锁定代码并运行它。等等……

如果您只需要第一个线程来执行该代码块,只需在它第一次运行时设置一个标志,对于连续的线程只需先检查该标志。

【讨论】:

  • 除了 id.ScanCode 之外,我还使用了一个 add'l 标志(私有变量),这似乎已经解决了。谢谢大家。
  • 我仍然很好奇如何多个线程可以运行 WndProc。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-02
  • 1970-01-01
相关资源
最近更新 更多