Использование 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++;
      }
    }
  }
}

Для простого межпоточного взаимодействия, подобного этому, подходит ли volatile здесь? Я понимаю, что i ++ не является атомарной операцией, но если один поток выполняет все приращения, а другой просто хочет прочитать его, чтобы увидеть, достигает ли он определенного порога, все в порядке, верно?

Edit: Конечно, я нашел еще один подобный вопрос с подробными ответами после факта.

6
задан Community 23 May 2017 в 10:34
поделиться