я должен заблокировать «событие»? - PullRequest
13 голосов
/ 05 февраля 2010

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

event foo;

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

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

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

1 Ответ

24 голосов
/ 05 февраля 2010

Блокировка на 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;

тогда вы автоматически получите «блокировку (это)» при добавлении / удалении, хотя вам придется вручную добавлять его при извлечении обработчика перед его вызовом (при условии, что вы хотите удостовериться, что прочитали последнюю написанную значение). Лично я не фанат блокировок «this», но вы можете не возражать - и это, безусловно, упрощает код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...