Есть два вопроса к коду, приведенному ниже:
Допустимо ли использовать yield return внутри блокировки?
Что произойдёт с блокировкой, когда мы будет крутить метод Get() в цикле foreach?
public IEnumerable
private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
Ответ
Смотрите, это возможно на уровне языка — компилятор не имеет возможности проверить. Но делать так не рекомендуется.
Общее правило такое: следует избегать вызова чужого кода под блокировкой. Допустим, вы нарушили правило и выполнили yield под блокировкой. Клиентский код может при этом сделать вызов в другой поток (если у нас нету многопоточности, то блокировки нам всё равно не нужны, правильно?).
foreach (SomeObject o in Get())
{
Dispatcher.Invoke(() => Process(o));
}
Если в методе Process будет браться та же блокировка, у вас будет взаимная блокировка, и код зависнет: Process будет дожидаться отпускания блокировки, а блокирующий код — возвращения из yield (то есть, следующей итерации цикла).
Комментариев нет:
Отправить комментарий