Save () не работает должным образом в MongoDB Back-end

Это зависит от того, что вы подразумеваете под потокобезопасностью. Если ваше определение включает в себя предотвращение NullReferenceException, то первым примером является more safe. Однако, если вы переходите к более строгому определению, в котором обработчики событий должны быть вызываться, если они существуют, то ни один из них не является безопасным. Причина связана с сложностями модели памяти и барьеров. Может быть, на самом деле есть обработчики событий, привязанные к делегату, но поток всегда читает ссылку как null. Правильный способ исправить это - создать явный барьер памяти в точке, где ссылка делегата будет записана в локальную переменную.

  • Используйте ключевое слово lock (или любой механизм синхронизации).
  • Используйте ключевое слово volatile для переменной события.
  • Используйте Thread.MemoryBarrier.

Несмотря на проблему неудобного обзора, которая мешает вам выполнять однострочный инициализатор, я по-прежнему предпочитаю метод lock.

protected virtual void OnSomethingHappened(EventArgs e)           
{          
    EventHandler handler;
    lock (this)
    {
      handler = SomethingHappened;
    }
    if (handler != null)           
    {          
        handler(this, e);          
    }          
}          

важно отметить, что в данном конкретном случае проблема барьер памяти, вероятно, спорный вопрос, потому что маловероятно, что читает переменные будут сняты вне вызовов методов. Но нет гарантии, особенно если компилятор решает встроить метод.

0
задан Muirik 18 March 2019 в 20:16
поделиться