Как: Написать потокобезопасный метод, который можно вызывать только один раз?

Я пытаюсь написать потокобезопасный метод, который может вызываться только один раз (для каждого экземпляра объекта). Исключение должно быть выброшено, если оно было вызвано ранее.

Я нашел два решения. Они оба правильные? Если нет, то что с ними не так?

  1. С lock:

    public void Foo()
    {
    блокировка (fooLock)
     {
    если (fooCalled) бросить новое InvalidOperationException();
    fooCalled = Истина;
     }
     …
    }
    частный объект fooLock = новый объект();
    частное логическое значение fooCalled;
    
  2. С Interlocked.CompareExchange:

    public void Foo()
    {
    если (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1)
    бросить новое исключение InvalidOperationException();
     …
    }
    частный int fooCalled;
    

    Если я не ошибаюсь, у этого решения есть то преимущество, что оно не требует блокировки (что в моем случае кажется неуместным) и требует меньшего количества приватных полей.

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

8
задан stakx supports GoFundMonica 1 March 2012 в 10:44
поделиться