2010-08-19 6 views
4

public class EventsType { public 이벤트 EventHandler> NewEvent;C# 이벤트 구현 (기사 대 반사기)

public void SmthHappened(string data) 
    { 
     MyEventArgs<Object> eventArgs = new MyEventArgs<Object>(data); 
     OnNewEvent(eventArgs); 
    } 

    private void OnNewEvent(MyEventArgs<Object> eventArgs) 
    { 
     EventHandler<MyEventArgs<Object>> tempEvent = NewEvent; 

     if (tempEvent != null) 
     {     
      tempEvent(this, eventArgs); 
     } 
    } 
} 

나는 C# 컴파일러는이 같은 NewEvent 번역 할 것으로 예상 :

private EventHandler<MyEventArgs<object>> _newEvent; 

public event EventHandler<MyEventArgs<object>> NewEvent 
{ 
    [MethodImpl(MethodImplOptions.Synchronized)] 
    add 
    { 
    _newEvent = (EventHandler<MyEventArgs<object>>)Delegate.Combine(_newEvent, value); 
    } 
    [MethodImpl(MethodImplOptions.Synchronized)] 
    remove 
    { 
    _newEvent = (EventHandler<MyEventArgs<object>>)Delegate.Remove(_newEvent, value); 
    } 
} 

을하지만, 반사경은 이런 식으로 구현되는 것을 말한다 :

public event EventHandler<MyEventArgs<object>> NewEvent 
{ 
    add 
    { 
     EventHandler<MyEventArgs<object>> handler2; 
     EventHandler<MyEventArgs<object>> newEvent = this.NewEvent; 
     do 
     { 
      handler2 = newEvent; 
      EventHandler<MyEventArgs<object>> handler3 = (EventHandler<MyEventArgs<object>>) Delegate.Combine(handler2, value); 
      newEvent = Interlocked.CompareExchange<EventHandler<MyEventArgs<object>>>(ref this.NewEvent, handler3, handler2); 
     } 
     while (newEvent != handler2); 
    } 
    remove 
    { 
     EventHandler<MyEventArgs<object>> handler2; 
     EventHandler<MyEventArgs<object>> newEvent = this.NewEvent; 
     do 
     { 
      handler2 = newEvent; 
      EventHandler<MyEventArgs<object>> handler3 = (EventHandler<MyEventArgs<object>>) Delegate.Remove(handler2, value); 
      newEvent = Interlocked.CompareExchange<EventHandler<MyEventArgs<object>>>(ref this.NewEvent, handler3, handler2); 
     } 
     while (newEvent != handler2); 
    } 
} 

것은, SMB 설명하세요 왜 나야?

답변

5

예 : C# 4 has made some changes in this area입니다. 그것은 잠금없이 thread-safe하게 만듭니다. 그게 유일한 변화는 아니며 클래스 내의 필드와 같은 이벤트에 대한 참조가 어떻게 변경되는지도 바뀝니다. + = 및 - =은 이제 뒷받침 필드로 직접 작업하는 것이 아니라 "추가"및 "제거"비트를 통과합니다.

이 변경은 이전 프레임 워크와 비교하여 C# 4 컴파일러로 컴파일 된 코드에 영향을줍니다. 만이 새로운 방법 (Monitor.TryEnter(object, out bool))을 사용하기 때문에 .NET 4에 대해 컴파일 된 코드에 영향을줍니다.

+0

Roslyn (C# 6)으로 컴파일 된 이벤트의 디 컴파일 된 소스를보고 있었는데 CompareExchange를 사용하여 do ... while 루프를 계속 볼 수 있습니다. Monitor.TryEnter()를 사용하는 버전은 무엇입니까? 기억 나니? –

0

당신이 기대하는 것은 간단한 스레드가 아닌 안전한 구현입니다. 이벤트 신텍스와 같은 필드는 항상 스레드 세이프 구문 (즉, 리플렉터 버전)을 제공합니다. 그들이 실현되는 방법 & 이벤트를 이해하려면 artcile을 참조하십시오.