我已经阅读了相当多的关于这个主题的帖子,我想我终于明白了volatile关键字在C#中是如何工作的.我仍然想在这里问一下,以确保我理解正确的概念.请考虑以下代码:
class ThreadWrapper { public bool Enabled { get; set; } private void ThreadMethod() { while (Enabled) { // ... Do work } } }
根据我的理解,如果另一个线程设置为Enabled = false,原始线程可能不会立即(或者可能永远?)看到此更改.为了确保编译器不优化对Enabled属性的访问并依赖缓存值,更改代码如下所示应该解决问题.
public bool Enabled { get {return mEnabled;} set {mEnabled=value;} } private volatile bool mEnabled;
现在,只要读取Enabled值,就可以保证获得最新值,对吗?如果是这样,我应该能够将它用作简单的信号或标志(就像我上面的那样).
作为另一个例子,请考虑以下事项:
class C { private volatile int i; private volatile bool enabledA; private volatile bool enabledB; void ThreadA() { i = 0; // Reset counter while (enabledA) { // .. Do some other repeated work if (i > 100) { // .. Handle threshold case } } } void ThreadB() { while (enabledB) { // .. Do work if (condition) // Some condition occurs that we want to count { i++; } } } }
对于像这样简单的线程间通信,这里的挥发性令人满意吗?我知道我不是一个原子操作,但是如果一个线程正在进行所有递增而另一个只是想读取它以查看它是否达到某个阈值,我们没关系吗?
编辑:我当然在事后找到了another similar question with detailed answers.
解决方法
我相信你是对的.
MSDN’s article on the volatile
keyword在其示例中使用了相同的技术.