2012-04-02 2 views
3

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

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

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

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

Use of unassigned local variable 'handler' 

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

ответ

3

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

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

    AnEvent -= OnEvent; 
} 

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

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

6

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

Он работает, хотя раньше вы назначили значение null для EventHandler.

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

 EventHandler handler=null; 

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

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

+1

Если вы это сделаете, у вас будет исключение null ref в вашем обратном вызове ... –

+2

Нет, попробуйте. Обработчик захватывается в закрытии. – aKzenT

+2

Эй, не проголосуйте меня, прежде чем вы даже попробовали! прочитайте, как работают затворы ... – aKzenT

Смежные вопросы