c# – 使用volatile进行.NET中线程之间的单向通信

我已经阅读了相当多的关于这个主题的帖子,我想我终于明白了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在其示例中使用了相同的技术.

相关文章

在要实现单例模式的类当中添加如下代码:实例化的时候:frmC...
1、如果制作圆角窗体,窗体先继承DOTNETBAR的:public parti...
根据网上资料,自己很粗略的实现了一个winform搜索提示,但是...
近期在做DSOFramer这个控件,打算自己弄一个自定义控件来封装...
今天玩了一把WMI,查询了一下电脑的硬件信息,感觉很多代码都...
最近在研究WinWordControl这个控件,因为上级要求在系统里,...