Я пытаюсь написать потокобезопасный метод, который может вызываться только один раз (для каждого экземпляра объекта). Исключение должно быть выброшено, если оно было вызвано ранее.
Я нашел два решения. Они оба правильные? Если нет, то что с ними не так?
С lock
:
public void Foo()
{
блокировка (fooLock)
{
если (fooCalled) бросить новое InvalidOperationException();
fooCalled = Истина;
}
…
}
частный объект fooLock = новый объект();
частное логическое значение fooCalled;
С Interlocked.CompareExchange
:
public void Foo()
{
если (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1)
бросить новое исключение InvalidOperationException();
…
}
частный int fooCalled;
Если я не ошибаюсь, у этого решения есть то преимущество, что оно не требует блокировки (что в моем случае кажется неуместным) и требует меньшего количества приватных полей.
Я также открыт для обоснованных мнений, какое решение следует предпочесть, и для дальнейших предложений, если есть лучший способ.