핵심 정리
csharp
// 1. 구독 등록
publisher.Changed += OnChanged;
// 2. publisher 내부에서 발생
Changed?.Invoke(this, EventArgs.Empty);
// 3. 더 이상 필요 없을 때 해제
publisher.Changed -= OnChanged;기본 구조
event 흐름은 결국 아래 세 단계로 읽으면 됩니다.
csharp
public 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;- publisher가
event를 선언한다 - subscriber가
+=로 핸들러를 등록한다 - publisher 내부에서만
Invoke로 이벤트를 발생시킨다
흐름 다이어그램
흐름 순서
text
[Publisher] [Subscriber]
│ │
│ ① event 선언 │
│ public event EventHandler Changed │
│ │
│◄────── ② += 핸들러 등록 ───────────│
│ │
│ ③ Changed?.Invoke() 호출 │
│──────── ④ 핸들러 실행 ────────────►│
│ │
│◄────── ⑤ -= 구독 해제 ────────────│체크포인트
| 단계 | 코드 | 설명 |
|---|---|---|
| 선언 | public event EventHandler E | publisher가 이벤트 소유 |
| 등록 | publisher.E += handler | subscriber가 콜백 연결 |
| 발생 | E?.Invoke(this, args) | publisher만 호출 가능 |
| 실행 | 등록된 모든 핸들러 순서대로 | multicast delegate |
| 해제 | publisher.E -= handler | 수명 관리 필수 |
주의할 점
publisher의 수명이 subscriber보다 길면 -= 해제를 빠뜨렸을 때 subscriber가 GC 대상이 되지 않아 메모리 누수가 생깁니다. UI 컨트롤이나 싱글톤 서비스처럼 수명이 긴 publisher에 구독할 때는 반드시 해제 시점을 함께 설계하세요.
delegate와 event의 개념적 차이, EventHandler<T> 시그니처, 커스텀 이벤트 인수에 대한 내용은 delegates와 events 카드를 참고하세요.
참고 링크
1 sources