2016-08-12 5 views
1

Я пытаюсь лучше понять, как работают события и их обработчик, но я не понимаю, почему при создании события обычно предпочтительнее поднимать идентичное событие, это наше событие. Чтобы быть более конкретным, если смотреть на MSDN документ (https://msdn.microsoft.com/en-us/library/db0etb8x.aspx) это выглядит так:EventHandler raise Событие должным образом

class Counter 
{ 
    private int threshold; 
    private int total; 

    public Counter(int passedThreshold) 
    { 
     threshold = passedThreshold; 
    } 

    public void Add(int x) 
    { 
     total += x; 
     if (total >= threshold) 
     { 
      ThresholdReachedEventArgs args = new ThresholdReachedEventArgs(); 
      args.Threshold = threshold; 
      args.TimeReached = DateTime.Now; 
      OnThresholdReached(args); 
     } 
    } 

    protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) 
    { 
     EventHandler<ThresholdReachedEventArgs> handler = ThresholdReached; 
     if (handler != null) 
     { 
      handler(this, e); 
     } 
    } 

    public event EventHandler<ThresholdReachedEventArgs> ThresholdReached; 
} 

То, что я не понимаю, почему «обработчик» создается в функции OnThresholdReached, вместо того, чтобы

protected virtual void OnThresholdReached(ThresholdReachedEventArgs e) 
    { 
     if (ThresholdReached!= null) 
     { 
      ThresholdReached(this, e); 
     } 
    } 

Почему мы должны создавать этот «обработчик»?

+0

@MattWilko - думаю, что это неправильно. Я почти уверен, что предложение в OP будет работать. Я считаю, что причина, по которой выполняется «копия» обработчика, связана с безопасностью потоков. Я помню, что рассматривал этот тот же самый вопрос в прошлом, но я не могу точно помнить, что я заключил lol ... –

+0

Мое «предложение» действительно работает, но все же, я уверен, что есть веская причина, по которой они хотят создать это обработчик;) – Belterius

+0

microsoft doc: https://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx делает это без «копирования», поэтому, если что-то происходит, это явно недостаточно для того, чтобы Microsoft не была последовательной. –

ответ

4

Рассмотрим этот код:

if (ThresholdReached!= null) 
    { 
     ThresholdReached(this, e); 
    } 

Что произошло бы в многопоточном коде, если обработчик ThresholdReached удаляется после if (ThresholdReached!= null), но перед ThresholdReached(this, e); называется?

Выполнение копии обработчика предотвращает возникновение этой ситуации и делает подъем потока событий безопасным.

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