언뜻 보면 이벤트를 발생시키는 작업은 그리 어려운 부분이 없어 보인다. 이벤트를 정의하고, 이벤트
를 발생시켜야 할 경우 이벤트를 호출하기만 하면 이벤트에 결합되어 있는 이벤트 핸들러가 호출될
것이기 때문이다. 멀티캐스트 델리게이트의 경우 이벤트에 결합된 이벤트 핸들러가 여러 개지만 내
부적으로 이를 순차적으로 호출해줄 것이므로 복잡성이 외부로 들어나지 않는다.
하지만 실제로는 이처럼 단순한 방식으로 이벤트를 호출하는 경우 다양한 문제가 발생하곤 한다.
우선 이벤트에 결합된 이벤트 핸들러가 없다면 어떻게 될까? 이벤트 핸들러가 결합되어 있는지를
확인하는 코드를 추가하면 된다고 생각할지 모르지만, 이벤트 핸들러가 결합되어 있는지를 확인하는
코드와 이벤트를 발생시키는 코드 사이에 경쟁 조건(race condition)이 발생할 가능성이 있다.
이 문제는 C# 6.0에 새롭게 추가된 null 조건 연산자(null conditional operator)를 사용하면 깔끔하게
해결할 수 있다.
먼저 에전 방식을 살펴보고 안전하게 이벤트를 발생시키기 위해서 무엇을 어떻게 해야 하는지
살펴보자. 간단한 이벤트 발생 코드는 다음과 유사할 것이다.
public class EventSource
{
private EventHandler<int> Updated;
public void RaiseUpdates()
{
counter++;
Updated(this, counter);
}
private int counter;
}
이 코드는 문제가 있는 코드다. 우선 Updated 이벤트에 이벤트 핸들러가 결합돼 잇지 않다면
NullReferenceException 예외가 발생한다. 이벤트 핸들러가 결합되지 안은 이벤트는 null 값을 갖기
때문이다. 따라서 이벤트를 발생시키기 이전에 유효한 이벤트 핸들러가 결합되었는지를 확인하도록
코드를 추가해야 한다.
public void RaiseUpdate()
{
counter++;
if (Updated != null)
Updated(this, counter);
}
이렇게 코드를 수정하면 대부분의 경우 잘 동작하지만 여전히 숨어 있는 버그가 있다.