Quick Flow
event는 subscriber가 handler를 등록하고, publisher가 내부에서 알림을 발생시키며, 필요 없어진 subscriber가 같은 handler를 해제하는 흐름입니다. 일반 event handler는 publisher 호출 중 동기로 실행됩니다.
publisher.Changed += OnChanged; // 1. 구독
publisher.Raise(); // 2. publisher 내부에서 발생
publisher.Changed -= OnChanged; // 3. 종료 시 해제- publisher만
Invoke할 수 있고, subscriber는+=와-=만 할 수 있습니다. - 등록 순서대로 handler가 실행되며, 예외가 나면 기본 호출은 이후 handler까지 진행하지 않습니다.
- publisher가 더 오래 살면 subscriber의
Dispose, 화면 종료, 작업 종료 지점에서 구독을 해제합니다.
연결 흐름
<ZoomImage src="/images/csharp/delegate-event-flow.svg" alt="publisher가 event를 선언하고 subscriber가 등록한 handler를 publisher 내부의 Invoke로 실행한 뒤 해제하는 흐름" caption="event는 알림의 발생 권한을 publisher에 남기고, subscriber에는 구독 권한만 줍니다." />
public sealed class Publisher
{
public event EventHandler? Changed;
public void Raise() => Changed?.Invoke(this, EventArgs.Empty);
}
var publisher = new Publisher();
publisher.Changed += OnChanged;
publisher.Raise();
publisher.Changed -= OnChanged;[Subscriber] -- += handler --> [Publisher event]
|
Raise / Invoke
|
[Subscriber handler] <-- synchronous invocation --실패와 종료
handler 하나가 예외를 던지면 multicast delegate의 기본 호출은 그 지점에서 중단됩니다. 모든 subscriber에 반드시 알림을 시도해야 한다면 publisher가 handler 목록을 순회하면서 예외 기록·재전파 기준을 명시해야 합니다.
Changed?.Invoke(...)는 호출 목록을 읽는 관례일 뿐, handler 내부의 비동기 작업을 기다리지 않습니다. 저장·네트워크처럼 완료 상태가 필요한 알림은 일반 event가 아니라 Func<..., Task>를 받는 async API로 모델링합니다.
구독한 lambda를 해제해야 한다면 같은 delegate 인스턴스가 필요합니다. 장수명 publisher는 subscriber를 붙잡을 수 있으므로, subscriber의 lifecycle 종료와 -=를 함께 설계합니다.
관련 참조
delegate 종류, EventHandler<T>, multicast 반환·예외 정책, IDisposable 구독 해제는 delegate와 event에서 확인합니다.
참고 링크
1 sources