1. 대리자 vs 이벤트 선언 방법

: 이벤트는 대리자를 event 키워드로 수식해서 만든다.

더보기

A.

이벤트는 대리자와 같은 기반을 가진 개념으로, 대리자를 이해한 후 이벤트를 학습해야 한다.

 

 

B.

이벤트가 대리자와 다른점은, 이벤트는 메서드 안에서만 호출해서 사용 가능하다는 점이다.

// 대리자 선언
delegate void Callback(string message);

class Button
{
    public Callback? MyHandler; // 대리자 필드

    public event Callback? Click_Signal; // 이벤트로 변경 (외부에서 Invoke 금지)

    public void RaiseClick(string message)
    {
        Click_Signal?.Invoke(message);
    }
}

class MainApp
{
    static void Main(string[] args)
    {
        var btn = new Button();

        // 대리자는. 외부에서도 직접 호출 가능 (안전하지 않을 수 있음)
        btn.MyHandler?.Invoke("대리자 직접 호출 예시");

        // 이벤트는, 외부에서 직접 호출 ❌
        // btn.Click_Signal?.Invoke("이벤트 직접 호출 예시"); // 컴파일 에러

        // 내부 메서드를 통해서만 실행 가능
        btn.RaiseClick("You've got mail.");

    }
}

 

  • 대리자 = "메서드 참조를 저장/실행할 수 있는 변수"
  • 이벤트 = "대리자를 이용하지만, 발행자 내부에서만 실행할 수 있는 안전한 신호 장치"

 


 

2. 예시

더보기

A.

대리자를 통해 콜백 개념을 익혔다면,

이벤트가 시작되는 로직과, 대리자로 연결하는 부분, 신호를 전달받아 동작하는 로직을 구분할 수 있다.

 

 

B. 가정

 

  • 아래 예제는, 버튼이 눌려지면, 레이블에 문자열이 수정되는 구조를 이벤트로 구현한다고 가정하자.
    eg) [버튼 클릭 > 이벤트(대리자)] > 레이블 수정
  • 예제 구조에서 구현된 이벤트는, 이벤트를 선언하는 목적이 아니다.
    레이블의 수정이 목적이다.
    • [1] 시작은 Button 객체의 click 함수의 실행
    • [2] 이벤트가 실행되면
    • [3] 목적은 Label 객체의 show 함수의 실행이다.
  • 이벤트는 click 함수가 show 함수를 실행하게 만드는 대리자(콜백)이다.
    이벤트는 최종 실행 목적인 show 함수를 기반으로 선언된다.

 

 

delegate void callback(string msg);

class Button
{
    public event callback EventHandler;

    public void click(string x) // 2.1 함수의
    {
        EventHandler(x); // 2.2 이벤트 동작

        // btn.click() -> btn.EventHandler() -> lbl.show() 순으로 함수가 호출된다.
        // 이벤트가 동작된 후 최종 실행 구조는 아래와 같다.
        //lbl.show("click~!!")
    }
}

class Label
{
    public void show(string x) // 4.1 함수의
    {
        Console.WriteLine("Lable print >> " + x); // 4.2 매개변수 전달받아 동작
    }
}

internal class Program
{
    static void Main(string[] args)
    {
        Button btn = new Button();
        Label lbl = new Label();

        // 버튼 객체의 이벤트(=대리자)에, 레이블 객체의 함수를 등록한다.
        btn.EventHandler += new callback(lbl.show); // 3. 이벤트에 연결된 lbl.show() 동작

        btn.click("click~!!"); // 1. 버튼의 click 함수가 실행되면
    }
}

 

3. 이벤트 실행 흐름 이해

: 소스코드는 한 줄 씩 실행된다.  실행 흐름을 이해해야 한다.

더보기

A. 예제1

// 버튼을 누르면, 레이블에 출력된다고 가정한다.

using System;

namespace EventTest
{
    delegate void Callback(string message);

    class Button 
    {
        public event Callback CollbackEvent;

        public void Check369(int number)  // [2]
        {
            int temp = number % 10;

            if (temp != 0 && temp % 3 == 0)
                CollbackEvent(String.Format("{0} : 짝", number));  // [3]
        }
    }

    class Label
    {
        public void ShowMsg(string message)   // [5]
        {
            Console.WriteLine(message);   // [6]
        }
    }

    class MainApp
    {
        static void Main(string[] args)
        {
            Button btn = new Button();
            Label lbl = new Label();

            // 버튼 객체의 이벤트(=대리자)에, 레이블 객체의 함수를 등록한다.
            // 버튼 객체의 이벤트(=대리자)에, 레이블 객체의 함수
            btn.CollbackEvent += new Callback(lbl.ShowMsg);   // [4]

            // 버튼이 눌려진다고 가정한다.
            // 버튼이 눌려질 때마다 정수 1~30을 순차적으로 전달한다.
            // 1. 버튼이 눌려지고 -> 2. Check369() 함수가 실행되고
            // 3. CollbackEvent가 실행되고, 매개변수로 "문자열"이 전달된다.
            // 4. CollbackEvent에 연결된, 레이블의 ShowMsg함수가 실행된다.
            for (int i = 1; i < 30; i++)
                btn.Check369(i); // [1]
        }
    }
}



B. 예제2

// 이것이 c#이다. 교재 496쪽 소스코드

using System;

namespace EventTest
{
    delegate void EventHandler(string message);

    class MyNotifier 
    {
        public event EventHandler SomethingHappened;
        public void DoSomething(int number)
        {
            int temp = number % 10;

            if ( temp != 0 && temp % 3 == 0)
            {
                SomethingHappened(String.Format("{0} : 짝", number));
            }
        }
    }

    class MainApp
    {
        static public void MyHandler(string message)
        {
            Console.WriteLine(message);
        }

        static void Main(string[] args)
        {
            MyNotifier notifier = new MyNotifier();
            notifier.SomethingHappened += new EventHandler(MyHandler);

            for (int i = 1; i < 30; i++)
            {
                notifier.DoSomething(i);
            }
        }
    }
}

 

 

예제 3

카운팅이라는 로직을 가진 객체의 이벤트가 동작할때마다, 텍스트박스 객체에 출력된다고 가정한다.

using System;

namespace delegate_test4
{
    delegate void A (string sender);

    class TextBox
    {
        private string title;
        public TextBox(string name)
        {
            this.title = name;
        }

        public void run(string run_msg)
        {
            Console.WriteLine( run_msg + title + "에서 출력!");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            TextBox TB1 = new TextBox("텍스트창1");
            TextBox TB2 = new TextBox("텍스트창2");
            TextBox TB3 = new TextBox("텍스트창3");
            TextBox TB4 = new TextBox("텍스트창4");

            Counting cnt = new Counting();
            cnt.Cnt_EventHandler += TB1.run;
            cnt.Cnt_EventHandler += TB2.run;
            cnt.Cnt_EventHandler += TB3.run;
            cnt.Cnt_EventHandler += TB4.run;

            cnt.nCnt();
        }
    }

    class Counting
    {
        public event A Cnt_EventHandler;

        public void nCnt()
        {
            for (int i = 0; i < 10; i++)
            {
                Cnt_EventHandler($"이벤트, {i+1}회 실행 >> ");
            }
        }
    }
}

 

 

 

4. 윈폼 예제

더보기

A. 구조 이해

 

button1 이라는 객체에, button1.Click 이벤트에, Form1의 button1_click( ) 함수가 등록되었다.

"Button 객체의 Event" 라는 대리자가 실행되면, 윈폼의 함수, 윔폼의 컨트롤, 또는 특정 실행 로직을 가진 함수가 실행되도록 구현하는 개념이다.

 

 


 

5. 윈폼 파일 복사 (동기 구조)

: (동영상 링크 ~ 8:00)

더보기

해당 로직은 동기화 방식으로, 파일 복사 실행중에는 UI가 멈춤

 

event_test  프로젝트 경로에  "파일 복사"에 사용 할 파일 src.mp4 파일이 있어야 합니다.

(TCP/IP 서버-클라이언트 구조에서 파일 전송으로 가정하고 접근합니다.)

 

이벤트 제공자 : button1.click

이벤트 가입자 : FileManager

 

환경: Visual Studio 2022, net8.0

event_test.zip
5.99MB

해당 로직은 동기화 방식으로, 파일 복사 실행중에는 UI가 멈춤


 

6. 윈폼 파일 복사 (비동기)

: (동영상 링크 8:00 ~ )

더보기

event_test  프로젝트 경로에  "파일 복사"에 사용 할 파일 src.mp4 파일이 있어야 합니다.

 

이벤트 제공자 : FileManager 

이벤트 가입자 : Form1

 

환경: Visual Studio 2022, net8.0

event_test (2).zip
5.98MB