C# 이벤트(Event), 게시자,구독자를 통한 이벤트처리 EventHandler를 통한 이벤트처리 이벤트 add, remove 접근자



C# 이벤트(Event), 게시자,구독자를 통한 이벤트처리 EventHandler를 통한 이벤트처리 이벤트 add, remove 접근자

C# 이벤트(Event), 게시자,구독자를 통한 이벤트처리  EventHandler를 통한 이벤트처리  이벤트 add, remove 접근자

C# 이벤트(Event) 게시자, 구독자를 통한 이벤트처리 EventHandler 실습 동영상 입니다.

강의자료 : http://ojc.asia/bbs/board.php?bo_table=LecCsharp&wr_id=411

C# 이벤트(Event)

윈도우 폼 등에서 특정 사건(Event, 마우스 클릭등)이 발생하면 인터럽트가 발생되고 이에 따라 윈도우 메시지가 발행되어 C#에 전달해 주는데 C# 클래스 내에는 이 이벤트 메시지, 사건(Event, 윈도우 버튼의 클릭등)이 일어났을 때 외부에 있는 이벤트 가입자에게 알려주고 이벤트 처리 메소드가 실행되게 된다.

이벤트는 선언된 클래스 내에서만 호출할 수 있는 특수한 종류의 멀티캐스트 델리게이트 이다. 클라이언트는 이벤트가 발생할 때 호출되어야 하는 메서드에 대한 참조를 제공하면서 이벤트를 구독(이벤트에 가입)하며 이러한 이벤트 핸들러 메소드는 add 및 remove 이벤트 접근자를 통해 이벤트 델리게이트의 호출 목록에 추가된다.

public event EventHandler Click
{
add…
remove…
}

대부분의 경우 이벤트 접근자를 제공할 필요가 없다. 코드에서 이벤트 접근자(add, remove)를 제공하지 않으면 컴파일러가 자동으로 추가한다. 물론 경우에 따라 사용자 지정 동작을 제공해야 할 수도 있다.

속성(Property)에서 get, set 처럼 event 에서도 add, remove 접근자를 사용할 수 있는데 add는 이벤트에 가입할 때 (+=) 호출되며 remove는 이벤트에서 탈퇴할 때(-=) 호출된다. 보통 이벤트를 만들 때 add, remove 접근자를 사용하지 않으면 C# 컴파일러가 자동으로 넣어준다.

닷넷 프레임워크의 이벤트 모델은 디자인 패턴의 옵저버 패턴과 비슷한데 어떤 객체에 관찰자(옵저버)를 등록하고 이벤트가 발생하면 옵저버로 통지해 준다. 이때 어떤 객체는 발행자(Publisher)가 되고 옵저버 객체들은 구독자(Subscriber)가 된다.

닷넷에서 이벤트는 클래스내에서 일종의 필드처럼 정의되며 event 라는 키워드를 통해 생성하고 public으로 선언되어도 외부 클래스에서는 호출이 불가능하다.(델리게이트는 가능)

이벤트에 가입하는 외부 가입자는 이벤트가 발생했을 때 어떤 메소드를 실행할지를 지정하는 데 이를 이벤트 핸들러 라고 한다. 이벤트에 가입하기 위해서는 += 연산자를 사용하며 삭제를 위해서는 -= 연산자와 델리게이트를 이용한다. 그러므로 하나의 이벤트에 여러개의 이벤트 핸들러(이벤트 처리 메소드)를 추가할 수 있으며 이벤트가 발생하면 순서대로 호출된다.

1. 게시자, 구독자를 통한 간단한 테스트

using System;

namespace ConsoleApplication1
{
//이벤트 게시자 클래스, 이벤트를 발생시키는 객체
class EventPublisher
{
public delegate void MyEventHandler(); //이벤트처리를위한델리게이트정의
public event MyEventHandler MyEvent; //이벤트 정의
public void Do()
{
//이벤트 가입자가 있는지 확인, 만약 구독자가 존재하는지 확인안하려면
// public event MyEventHandler MyEvent = delegate { }; 라고 하면된다.
//if (MyEvent != null) { MyEvent(); //이벤트 발생 }
MyEvent?.Invoke();
}
}

//구독자 클래스
class Subscriber
{
static void Main(string[] args)
{
EventPublisher p = new EventPublisher();

//구독자의 이벤트 처리 메소드를 등록
//이벤트를 발생하면 호출될 메소드를 정의, 여기서는 doAction 메소드 호출
//MyEvent라는 이벤트에 이벤트핸들러인 델리게이트를 통해 메소드를 등록
//MyEvent라는 이벤트가 발생하면 델리게이트가 참조하는 메소드 doAction() 실행
p.MyEvent += new EventPublisher.MyEventHandler(doAction);

//테스트를 위해 do() 메소드를 호출하여 이벤트 발생
//실제 윈폼등에서는 버튼등을 클릭하면 자동으로 이벤트가 발생하지만
//콘솔 프로그램이라서 메소드를 호출하는 것이다.
p.Do();
}

//MyEvent라는 이벤트가 발생하면 호출되는 메소드
static void doAction() {
Console.WriteLine(“MyEvent라는 이벤트 발생…”);
}
}
}

2. System.EventHandler 델리게이트를 통한 이벤트 처리

이번에는 System.EventHandler라는 C#에서 제공하는 델리게이트를 이용해 보자.

EventHandler 클래스는 이벤트를 위한 델리게이트로 윈도우폼 버튼 객체의 Click 이벤트 등에서 사용되는 델리게이트이다. (이벤트 발생시 전달할 데이터가 없는 경우에 주로 사용)

EventHandler 클래스의 생김새는 다음과 같다.

public delegate void EventHandler(Object sender, EventArgs e)
sender : 이벤트가 발생한 객체, Publisher자신의 참조
e : 이벤트 발생시 전달할 데이터, 만약 전달할 데이터가 있는 경우 EventArgs 클래스를 상속하여 정의한다.
그러므로 이 델리게이트가 참조하는 메소드인 doAction 메소드 역시 이러한 모습이어야 한다.

using System;
namespace ConsoleApplication1
{

//이벤트 게시자 클래스
class EventPublisher
{
//public delegate void MyEventHandler();
//이벤트 처리를 위한 델리게이트 정의
public event EventHandler MyEvent; //이벤트 정의
public void Do()
{
MyEvent?.Invoke(this, EventArgs.Empty); //이벤트 발생
}
}

//구독자 클래스
class Subscriber
{
static void Main(string[] args)
{
EventPublisher p = new EventPublisher();
p.MyEvent += new EventHandler(doAction);
p.Do();
}

//MyEvent 이벤트가 발생하면 호출되는 메소드
//System.EventHandler의 기본형태가 매개변수 2개받고,
//리턴형이 void형 이므로 같은 형태로 만든다.
static void doAction(object sender, EventArgs e)
{
Console.WriteLine(“MyEvent라는 이벤트 발생…”);
}
}

}

위 예제에서 public event EventHandler MyEvent; 는 다음과 같이 변환된다.
private EventHandler _MyEvent;

public event MyEvent {
add { _MyEvent += new EventHandler(value); }
remove { _MyEvent -= new EventHandler(value); }
}