C#等待计数器值失败

C#等待计数器值失败,c#,locking,C#,Locking,我有一段代码,它使用回调修改来自其他线程的计数器值。我对它使用lock,并使用empty while循环检查计数器==0。在VisualStudio中运行时,它可以完美地工作。然而,在“释放”它并从二进制运行之后,它就冻结了。下面介绍了while循环以及回调方法体 是什么原因造成的 谢谢 public void someMethod() { //starting a bunch of threads calling the callback method while(counter &

我有一段代码,它使用回调修改来自其他线程的计数器值。我对它使用lock,并使用empty while循环检查计数器==0。在VisualStudio中运行时,它可以完美地工作。然而,在“释放”它并从二进制运行之后,它就冻结了。下面介绍了while循环以及回调方法体

是什么原因造成的

谢谢

public void someMethod() {
 //starting a bunch of threads calling the callback method
    while(counter > 0) {}
}

public void Callback()
    {
        lock (this)
        {
            countdown--;
        }
    }
每次访问线程之间共享的变量时都需要锁,而不仅仅是在一个位置。在这种情况下,
while
循环中的代码在访问
计数器
时没有引入内存障碍,因此允许抖动进行优化,例如仅读取缓存版本的值,甚至注意到该值不能写入,从而避免重复读取

在这种非常特殊的情况下,您可以使用
Volatile.Read(ref counter)
,它可能会工作,但是您应该非常小心尝试使用无锁或低锁编程,甚至使用这些低级别同步原语。您应该努力使用更高级别的同步原语。在这种特定情况下,
信号量
将是合适的。将其初始化为倒计时值,在回调中释放它,并在方法中等待它


锁定隐式参数(
)也是代码气味。您应该努力只锁定在一个非常小、严格控制的范围内的对象,以避免由于从广泛的代码基础范围中取出对象上的锁而导致死锁。

您的while循环在一个方法之外……回调是从另一个线程运行的。这是另一个方法的片段。
countdown
初始化在哪里?
计数器在哪里初始化?他们之间有联系吗?你为什么空着跑一段时间?为什么不使用
任务。等待所有
?这么多问题…嗨,戴夫,我很清楚这项任务。等等。然而,手头的具体任务是使用锁和计数器;)Servy的回答帮助我解决了这个问题。Servy,关于JIT优化,你是对的。非常感谢。我知道更高级别的原语,但是任务是使用同步的原语。谢谢你的帮助