2024. 9. 25. 19:55ㆍc#
C# 이벤트(Event) 생성 및 구독
이벤트(Event)는 객체 간의 의사소통을 위한 중요한 메커니즘입니다.
특히 발생한 특정 작업에 대한 응답으로 다른 메서드가 호출되도록 설계할 때 유용합니다.
이 글에서는 C#에서 이벤트를 생성하고, 구독하며, 사용하는 방법을 설명하겠습니다.
1. C# 이벤트의 기본 개념
이벤트(Event)는 특정 행동(action)이 발생했을 때 실행되는 메커니즘입니다.
이벤트는 발생자(publisher)와 구독자(subscriber) 모델로 동작하며, 발행자는 이벤트를 발생시키고 구독자는 해당 이벤트를 처리하는 구조입니다.
이벤트는 보통 델리게이트(delegate)를 기반으로 하여,
어떤 동작이 발생할 때 이를 감지하고 콜백으로 동작을 처리합니다.
2. 이벤트 선언 및 구독
이벤트를 선언하려면 먼저 델리게이트를 선언하고, 이를 통해 이벤트 핸들러를 정의해야 합니다.
1) 델리게이트 선언
이벤트는 특정 동작을 수행할 메서드 참조로 사용되므로, 델리게이트가 먼저 선언되어야 합니다. 일반적으로 반환형은 void이며, 이벤트 처리와 관련된 매개변수를 포함할 수 있습니다.
public delegate void NotifyEventHandler(string message);
2) 이벤트 선언
델리게이트를 기반으로 이벤트를 선언할 수 있습니다. 이벤트는 event 키워드를 사용하여 선언합니다.
public class Publisher
{
public event NotifyEventHandler OnNotify;
public void TriggerEvent(string message)
{
if (OnNotify != null)
{
OnNotify(message); // 이벤트 발생
}
}
}
위 코드에서 OnNotify 이벤트는 델리게이트 NotifyEventHandler를 기반으로 선언되었습니다.
이 이벤트는 TriggerEvent 메서드를 통해 발생될 수 있습니다.
3) 이벤트 구독
이벤트를 사용하려면 구독(subscribe) 과정을 통해 해당 이벤트를 처리할 메서드를 등록해야 합니다. 구독은 += 연산자를 사용하여 메서드를 이벤트에 등록합니다.
public class Subscriber
{
public void OnEventTriggered(string message)
{
Console.WriteLine($"이벤트 수신: {message}");
}
}
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
publisher.OnNotify += subscriber.OnEventTriggered; // 이벤트 구독
publisher.TriggerEvent("이벤트 발생!"); // 출력: 이벤트 수신: 이벤트 발생!
이 코드에서 subscriber 객체는 OnNotify 이벤트를 구독하고 있으며, TriggerEvent 메서드를 통해 이벤트가 발생하면 OnEventTriggered 메서드가 호출됩니다.
3. 이벤트 구독 취소
이벤트 구독을 취소하려면 -= 연산자를 사용하여 구독을 해제할 수 있습니다.
publisher.OnNotify -= subscriber.OnEventTriggered;
구독을 취소하면, 이벤트가 발생해도 더 이상 해당 메서드가 호출되지 않습니다.
4. 이벤트와 EventHandler
C#에서 이벤트를 선언할 때 EventHandler 델리게이트를 사용하는 것이 일반적입니다.
EventHandler는 반환형이 void이며, 이벤트 처리 시 사용되는 매개변수로 객체와 이벤트 데이터를 전달하는 표준 델리게이트 형식입니다.
1) EventHandler 사용 예시
public class Publisher
{
public event EventHandler OnNotify;
public void TriggerEvent()
{
if (OnNotify != null)
{
OnNotify(this, EventArgs.Empty); // 이벤트 발생
}
}
}
public class Subscriber
{
public void OnEventTriggered(object sender, EventArgs e)
{
Console.WriteLine("이벤트 수신");
}
}
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
publisher.OnNotify += subscriber.OnEventTriggered;
publisher.TriggerEvent(); // 출력: 이벤트 수신
여기서 OnNotify 이벤트는 EventHandler 델리게이트를 기반으로 선언되었으며, 이벤트가 발생할 때는 sender 객체와 EventArgs 인스턴스가 전달됩니다.
5. 이벤트와 EventArgs
이벤트에 대한 추가 데이터를 전달하고 싶을 때는 EventArgs를 상속받아 사용자 정의 이벤트 데이터 클래스를 만들 수 있습니다.
1) EventArgs 확장
public class NotifyEventArgs : EventArgs
{
public string Message { get; private set; }
public NotifyEventArgs(string message)
{
Message = message;
}
}
2) 사용자 정의 EventArgs를 사용하는 이벤트
public class Publisher
{
public event EventHandler<NotifyEventArgs> OnNotify;
public void TriggerEvent(string message)
{
if (OnNotify != null)
{
OnNotify(this, new NotifyEventArgs(message));
}
}
}
public class Subscriber
{
public void OnEventTriggered(object sender, NotifyEventArgs e)
{
Console.WriteLine($"이벤트 수신: {e.Message}");
}
}
Publisher publisher = new Publisher();
Subscriber subscriber = new Subscriber();
publisher.OnNotify += subscriber.OnEventTriggered;
publisher.TriggerEvent("사용자 정의 이벤트 발생!"); // 출력: 이벤트 수신: 사용자 정의 이벤트 발생!
위 예제에서 NotifyEventArgs는 이벤트 발생 시 추가 정보를 전달하는 데 사용되며, 이벤트 핸들러는 이 데이터를 받을 수 있습니다.
6. 멀티캐스트 이벤트
이벤트는 여러 메서드를 구독할 수 있는 멀티캐스트 형태로 동작할 수 있습니다.
즉, 하나의 이벤트에 여러 개의 이벤트 핸들러가 등록되면, 이벤트 발생 시 해당 메서드들이 모두 호출됩니다.
publisher.OnNotify += subscriber.OnEventTriggered;
publisher.OnNotify += AnotherSubscriberMethod; // 추가적인 구독
publisher.TriggerEvent("이벤트 발생!"); // 두 개의 핸들러 모두 호출
7. 이벤트의 장단점
장점:
- 모듈화: 이벤트는 발행자와 구독자 간의 결합을 느슨하게 하여 코드의 모듈화와 재사용성을 높입니다.
- 유연성: 다양한 구독자가 동일한 이벤트에 다양한 방식으로 응답할 수 있어 유연한 설계가 가능합니다.
- 멀티캐스트 지원: 여러 메서드를 한 번에 구독하고 처리할 수 있습니다.
단점:
- 디버깅 어려움: 구독된 메서드가 동적으로 연결되기 때문에 어떤 메서드가 호출되는지 추적하기 어려울 수 있습니다.
- 성능 저하: 이벤트 구독자가 많아질수록 이벤트 처리 시간이 길어질 수 있습니다.
C#의 이벤트는 객체 간 비동기 통신을 가능하게 하며, 이벤트 기반 프로그래밍의 핵심 요소입니다.
이벤트를 통해 코드의 재사용성과 모듈성을 높일 수 있으며, 다양한 동작에 대응하는 유연한 설계를 가능하게 합니다.
이벤트를 사용할 때는 EventHandler와 EventArgs를 적절히 활용하여 이벤트 데이터의 전송 및 처리를 구조화하는 것이 중요합니다.
'c#' 카테고리의 다른 글
c# LINQ (Language Integrated Query) 기초 (2) | 2024.09.27 |
---|---|
C# 람다 표현식(Lambda Expression)의 사용법 (1) | 2024.09.25 |
c# 델리게이트(delegate)의 개념과 사용법 (0) | 2024.09.25 |
c# 람다(Lambda) 표현식 (0) | 2024.09.25 |
c# JSON, XML 데이터 처리 (0) | 2024.09.20 |