Отсоединение обработчика при первом вызове - PullRequest
3 голосов
/ 02 апреля 2012

Я хотел бы вызвать обработчик событий только один раз, а затем отключить его.Я пытался написать:

EventHandler handler = (s, e) =>
{
    // Do something
    //
    // blabla

    // Detach the handler
    SizeChanged -= handler;
};
SizeChanged += handler;

Однако на линии SizeChanged -= handler я получаю эту ошибку

Use of unassigned local variable 'handler'

У вас есть идеи, как мне поступить?Я думал об использовании логического флага, но я сделаю это, только если я не смогу найти способ отсоединить обработчик.

Ответы [ 2 ]

6 голосов
/ 02 апреля 2012

Компилятор C # сначала создает лямбда-выражение, которое вы написали, прежде чем присваивать результат переменной. Поэтому, когда лямбда определена, обработчик не имеет значения.

Хотя это работает, если вы ранее присвоили EventHandler значение null.

Поскольку это замыкание и локальные переменные захватываются в замыкании, во время вызова обработчик будет иметь правильное значение и будет работать:

        EventHandler handler=null;

        handler = (s, e) =>
        {
            // Do something 
            SizeChanged -= handler;
        };
        SizeChanged += handler; 

Для всех людей, проголосовавших вниз: Это не вызовет исключение NullReferenceException. handler - это локальная переменная, которая фиксируется в замыкании, поэтому значение обработчика внутри лямбды будет меняться при изменении в методе, который содержит замыкание. Я проверил это на самом деле на моем компьютере, и он отлично работает.

3 голосов
/ 02 апреля 2012

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

private void OnEvent(object sender, EventArgs e)
{
    // Do something

    AnEvent -= OnEvent;
}

private void RegisterOnce()
{
    AnEvent += OnEvent;
}

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

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