C#等待计数器值失败

时间:2014-11-07 21:43:16

标签: c# locking

我有一段代码片段,它使用回调来修改其他线程的计数器值。我正在使用锁定它并清空while循环以检查计数器是否== 0.它在Visual Studio中运行时效果很好。但是,在“释放”它并从二进制文件运行后它就会冻结。 while循环如下所示,以及回调方法体。

可能是什么造成的?

谢谢,

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

public void Callback()
    {
        lock (this)
        {
            countdown--;
        }
    }

1 个答案:

答案 0 :(得分:2)

每次访问线程之间共享的变量时,都需要锁定,而不仅仅是在一个位置。在这种情况下,while循环中的代码在访问counter时不会引入内存障碍,因此允许JITter进行优化,例如只读取值的缓存版本,甚至注意到该值无法写入,因此无法重复读取。

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

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