C#等待计数器值失败
我有一段代码,它使用回调修改来自其他线程的计数器值。我对它使用lock,并使用empty while循环检查计数器==0。在VisualStudio中运行时,它可以完美地工作。然而,在“释放”它并从二进制运行之后,它就冻结了。下面介绍了while循环以及回调方法体 是什么原因造成的 谢谢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 &
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优化,你是对的。非常感谢。我知道更高级别的原语,但是任务是使用同步的原语。谢谢你的帮助