Можно ли использовать Monitor.PulseAll безоговорочно? - PullRequest
1 голос
/ 16 апреля 2011

Например, каждый раз, когда завершается асинхронная операция, которая влияет на состояние приложения, я делаю это

lock (_parent._stateObj) {

    _parent._asyncOperations.Remove(this);

    Monitor.PulseAll(_parent._stateObj);

}

Я делаю это так, чтобы все, что ожидает завершения операций, например, процедура выхода из системы, были уведомлены.

Должен ли я / я должен делать что-то более похожее на

lock (_parent._stateObj) {

    _parent._asyncOperations.Remove(this);

    if (_parent._loggingOut) Monitor.PulseAll(_parent._stateObj);

}

Просто пытаюсь выяснить, должен ли я всегда быть пульсирующим при изменении внутреннего состояния приложения. И в большой библиотеке с в основном асинхронными вызовами, правда ли, что я должен более или менее всегда использовать PulseAll, поскольку может иметь место любое количество асинхронных вызовов, которые «зарегистрировались» в основном состоянии библиотеки?

Надеюсь, это имеет смысл

1 Ответ

1 голос
/ 13 июня 2011

Да, это обычно приемлемо, а иногда даже обязательно, к PulseAll безоговорочно.Самая важная вещь, которую нужно помнить, - это всегда перепроверять условие ожидания при вызове Wait.

public void WaitingThread()
{
  lock (mylock)
  {
    while (!CanProceed())
    {
      Monitor.Wait(mylock);
    }
    // The wait condition is finally satisfied so we can proceed now.
  }
}

Так что, если у вас есть сторона блокировки схемы PulseAll\Wait, закодированная правильно, тогда это обычно не имеет значения, как генерируются импульсы.Не имея лучшего понимания вашей конкретной ситуации, я не могу точно сказать, какая стратегия пульсации является оптимальной, но я думаю, что, по крайней мере, могу сказать, что пульс безоговорочно не вызовет никаких непреднамеренных побочных эффектов (опять же, при условии, что сторона ожидания закодирована правильно).

...