Я должен заблокировать "событие"?

Я должен заблокировать событие в следующем случае:

событие foo;

поток A: вызовет foo + = обработчик;

поток B: вызовет foo - = обработчик;

Я должен заблокировать foo?

Ответы

Ответ 1

Блокировка foo - плохая идея, потому что значение будет меняться каждый раз. Вы должны заблокировать переменную, которая не изменяется:

private readonly object eventLock = new object();
private EventHandler fooHandler;

public event EventHandler Foo
{
    add
    {
        lock (eventLock)
        {
            fooHandler += value;
        }
    }
    remove
    {
        lock (eventLock)
        {
            fooHandler -= value;
        }
    }
}

private void OnFoo(EventArgs e)
{
    EventHandler handler;
    lock (eventLock)
    {
        handler = fooHandler;
    }
    if (handler != null)
    {
        handler(this, e);
    }
}

Обратите внимание, что если вы используете полевое событие, например:

public event EventHandler Foo;

то вы автоматически получите "lock (this)" на add/remove, хотя вам придется вручную добавить его при извлечении обработчика перед его вызовом (при условии, что вы хотите, чтобы вы прочитали последнюю написанную стоимость). Лично я не поклонник блокировки на "this", но вы можете не возражать - и это, безусловно, делает более простой код.