Проблема не заключалась бы в том, чтобы встроить метод - это было бы, если бы JITter делал интересные вещи с доступом к памяти независимо от того, был ли он встроен.
Однако я не верю, что - это, в первую очередь, проблема. Это было высказано как беспокойство несколько лет назад, но я считаю, что это было расценено как некорректное чтение модели памяти. Существует только одно логическое «чтение» переменной, и JITter не может оптимизировать это так, чтобы значение изменялось между одним чтением копии и вторым чтением копии.
РЕДАКТИРОВАТЬ: Просто чтобы уточнить, я точно понимаю, почему это вызывает проблемы для вас. В основном у вас есть два потока, модифицирующих одну и ту же переменную (так как они используют захваченные переменные). Вполне возможно, что код будет выглядеть так:
Thread 1 Thread 2
myEvent += myListener;
if (myEvent != null) // No, it's not null here...
myEvent -= myListener; // Now it's null!
myEvent(null, EventArgs.Empty); // Bang!
Это немного менее очевидно в этом коде, чем обычно, поскольку переменная является захваченной переменной, а не обычным полем static / instance. Тот же принцип применяется, хотя.
Смысл подхода безопасного повышения состоит в том, чтобы сохранить ссылку в локальной переменной, которую нельзя изменить из других потоков:
EventHandler handler = myEvent;
if (handler != null)
{
handler(null, EventArgs.Empty);
}
Теперь не имеет значения, изменяет ли поток 2 значение myEvent
- он не может изменить значение обработчика, поэтому вы не получите NullReferenceException
.
Если JIT выполняет inline SafeRaise
, он будет встроен в этот фрагмент - потому что встроенный параметр заканчивается как новая локальная переменная, эффективно. Проблема была бы только в том случае, если JIT неправильно указывал на это, сохраняя два отдельных чтения myEvent
.
Теперь о том, почему вы только видели, как это происходило в режиме отладки: я подозреваю, что с подключенным отладчиком у потоков гораздо больше возможностей прерывать друг друга. Возможно, произошла какая-то другая оптимизация, но она не внесла поломок, так что все в порядке.