.NET 4.0 이후 자동 생성 된 추가/제거 이벤트 핸들러는 스레드 안전 (here 및 here)입니다. 따라서 노출 된 이벤트에 리스너를 등록한 클라이언트는 레이스없이 여러 스레드에서 동시에 수행 할 수 있습니다.다중 스레드 환경에서 이벤트 올리기
하지만 스레드를 안전하게 실행하려면 어떻게해야합니까? 권장되는 방법은 다음 (here) 것 같다 그러나
public event EventHandler MyEvent;
protected void OnMyEvent(EventArgs e)
{
EventHandler myEvent = MyEvent;
if (myEvent != null)
{
myEvent(this, e);
}
}
, 나는 더 이상이 올바른 생각하지 않는 .NET 메모리 모델 (예를 들어, MSDN 잡지 2012-12 및 2013-01) 읽은 것을 가지고.
public event EventHandler MyEvent;
protected void OnMyEvent(EventArgs e)
{
// JIT removed the local variable and introduced two memory reads instead.
if (MyEvent != null)
{
// A race condition may cause the following line to throw a NullReferenceException.
MyEvent(this, e);
}
}
지역 변수를 제거하고는 않기 때문에 반복 메모리 읽기 사용이 법적 : 내 관심사는 메모리가 컴파일러에 의해 도입 될 수있다 그래서 위의 코드는이 같은 것으로 JIT - 테드가 될 수 읽입니다 단일 스레드 환경에서 실행될 경우 메서드의 동작을 변경하지 않습니다. 이것은 ECMA 사양 (ECMA-335: I.12.6.4)입니다. 이해하기 쉬운 예제는 MSDN 매거진의 2013-01 호에서도 제공됩니다.
여기에 뭔가가 있습니까? 그렇지 않은 경우 해결 방법을 알려주십시오.
지적 해 주셔서 감사합니다. 나는 SO와 인터넷을 수색했지만 분명히 그 자리를 놓쳤다. 내 두 센트를 추가하려면 실제로 당신이 말하는 질문에 대해 잘못된 대답이 선택되었다고 생각합니다. 올바른 하나가이 것 같습니다 - http://stackoverflow.com/a/2365885/385737. ECMA 사양은 반복적 인 메모리 읽기로 지역 변수를 대체 할 수있게합니다. – Tomas
내 자신의 질문을 두 번 더 추가 - [this] (http://stackoverflow.com/questions/16162745/event-raising-and-read-introduction-in-net-4-5) 및 특히 [this] (http://stackoverflow.com/questions/14799876/read-introduction-in-c-sharp-how-to-protect-against-it) 위대한 답은 Eric Lippert입니다. – Tomas