본문 바로가기

(신)회사/개인 공부

델리게이트 & 이벤트 (delegate & event)

델리게이트는 무엇인가요?

델리게이트는 "연락 방법"이라고 생각하면 됩니다. 예를 들어, 학교 선생님이 여러 학생들에게 "특정 시간이 되면 집에 가라"라고 알려줄 연락 방법을 정해놓는 것과 비슷합니다. 이때 델리게이트는 "어떻게 연락할 것인지"를 정해주는 역할이에요. 예를 들어 전화, 이메일, 문자 메시지 등 여러 방법이 있을 수 있겠죠.


이벤트는 무엇인가요?

이벤트는 "일어나는 일"이라고 생각하면 됩니다. 예를 들어, 학교 종이 울리는 게 이벤트입니다. 종이 울리면 "집에 가라"는 메시지를 받게 되겠죠. 이 이벤트는 선생님이 준비해 놓은 델리게이트, 즉 연락 방법을 사용해서 알려주게 돼요.


이벤트 핸들러는 무엇인가요?

이벤트 핸들러는 "실제로 행동하는 것"입니다. 종이 울리면 학생들이 집에 가는 행동을 하는 것처럼, 이벤트가 발생했을 때 어떻게 반응할지를 정해주는 게 이벤트 핸들러입니다. 이벤트 핸들러는 이벤트가 발생했을 때 실행되는 특별한 메서드입니다.


델리게이트와 이벤트의 관계

이벤트는 "일이 발생했을 때 실행할 메서드"를 연결할 수 있도록 도와줍니다. 그런데 이벤트는 어떤 메서드를 연결할 수 있는지를 알아야 하죠. 바로 이때 델리게이트가 필요합니다.

델리게이트는 이벤트가 연결할 수 있는 메서드의 '형태'를 알려주는 역할을 합니다. 즉, 델리게이트는 "이 이벤트는 이런 형태의 메서드만 연결할 수 있어"라고 규칙을 정해주는 것입니다.

예시로 이해해보기

이걸 학교의 알림 시스템으로 비유해 볼게요:

  • 이벤트: 학교에서 알림을 보내는 시스템 (예: "수업이 시작됩니다!"라고 알림을 보내는 것).
  • 델리게이트: 알림을 받을 수 있는 방법의 형태 (예: "학생에게 문자 보내기"나 "교사에게 이메일 보내기"는 각기 다른 방법의 형태를 가짐).

public delegate void 알림형태(string 메시지);라고 하면, 이 델리게이트는 문자나 이메일 같은 메서드들이 string 메시지를 받아야 한다고 정해주는 겁니다.

public event 알림형태 수업알림;이라고 하면, 이 수업알림 이벤트는 string 메시지를 받는 메서드만 연결할 수 있어요.

델리게이트가 없는 경우

만약 델리게이트가 없다면, 이벤트가 어떤 메서드를 연결할 수 있는지 알 방법이 없어요. 이벤트는 메서드의 형태(매개변수와 반환 타입)를 알아야 하는데, 델리게이트가 그 형태를 알려주지 않으면 이벤트는 어떤 메서드가 적합한지 모릅니다. 그래서 델리게이트가 필요합니다.

간단히 말하면:

  • 델리게이트는 "이 이벤트는 이런 형태의 메서드만 받아"라고 정하는 역할.
  • 이벤트는 그 정해진 형태에 맞는 메서드만 연결할 수 있어요.

그래서 델리게이트가 없으면 이벤트는 어떤 메서드와 연결할 수 있는지 알 수 없어 동작하지 않게 됩니다.


코드의 주요 개념 및 설명 (직접 만든 테스트 프로그램에서 인용)

1. 델리게이트와 이벤트 정의

public delegate void Process_Received_Data_And_Send_Response_Event(object sender, Process_Received_Data_EventArgs args);
public event Process_Received_Data_And_Send_Response_Event Process_Received_Data_Event;

public class Process_Received_Data_EventArgs : EventArgs
        {
            public string DUTY_DVS_CD;      // 작업 구분 코드
            public string REC_LEN;          // 레코드 길이 코드
            public string REQ_SNO;          // 요청 고유 번호
            public string REQ_DTM;          // 요청 시간
            public string PRCR_NO;          // 카드 번호
            public string PASS_DC_DVS_CD;   // 할인 종류 코드
            public string AGRG_TROA_CD;     // 교통 기관 코드
            public string EXTL_STN_NO;      // 외부 역 번호
            public string PASSAM_ID;        // 정기권 ID
            public string RAIL_CHG_EQPM_NO; // 충전 장비 번호
            public Socket handle;           // 소켓 핸들러, 클라이언트 소켓을 참조함.
        }

 

  • 델리게이트: Process_Received_Data_And_Send_Response_Event는 특정 형식의 메서드를 참조할 수 있도록 정의한 델리게이트입니다. 이 델리게이트는 이벤트가 발생할 때 호출할 메서드의 형식을 정의합니다.
  • 이벤트: Process_Received_Data_Event는 이 델리게이트를 기반으로 한 이벤트입니다. Process_Received_Data_Event는 특정 조건에서 발생하여 외부에서 이벤트 핸들러 메서드를 실행할 수 있도록 합니다.

2. 이벤트 발생 및 데이터 처리 메서드

private async Task Process_Received_Data(Socket _handler, byte[] _receive_Data_Array)
{
    // 수신된 데이터를 구조체에 저장하는 부분
    Process_Received_Data_Struct rec_Data = new Process_Received_Data_Struct(0);

    try
    {
        // 수신 데이터를 각 필드에 저장
        rec_Data.DUTY_DVS_CD = Cls_APP.Extract_Array_By_Count(_receive_Data_Array, 2);
        // ... (다른 데이터 필드도 유사하게 저장)
        rec_Data.handle = _handler;

        // 이벤트를 발생시켜 연결된 이벤트 핸들러를 호출
        Process_Received_Data_Event(this, new Process_Received_Data_EventArgs
        {
            DUTY_DVS_CD = Cls_APP.Byte_Array_To_Ascii_String(rec_Data.DUTY_DVS_CD),
            REC_LEN = Cls_APP.Bytes_To_Decimal(rec_Data.REC_LEN),
            // ... (다른 필드들도 초기화)
            handle = rec_Data.handle
        });
    }
    catch
    {
        // 예외 처리
    }
}

3. 이벤트 핸들러 연결 및 처리

// 이벤트 핸들러를 이벤트에 연결하는 코드
cls_Socket_Server.Process_Received_Data_Event += cls_Socket_Server_Received_Data_And_Sned_Response_Data_Event;
private async void cls_Socket_Server_Received_Data_And_Sned_Response_Data_Event(object sender, Cls_Socket_Server.Process_Received_Data_EventArgs args)
{
    try
    {
        // 수신된 데이터를 UI 요소에 표시
        Cls_APP.C_Safe_Set_Text(tbox_DUTY_DVS_CD_REC, args.DUTY_DVS_CD);
        // ... (다른 텍스트 박스에도 유사하게 표시)

        // 처리된 데이터를 리스트로 저장
        List<byte[]> process_Received_Data = new List<byte[]>
        {
            Cls_APP.Ascii_String_To_Byte_Array(args.DUTY_DVS_CD),
            Cls_APP.Ascii_String_To_Byte_Array(args.REQ_SNO),
            Cls_APP.Ascii_String_To_Byte_Array(args.REQ_DTM),
            Cls_APP.Ascii_String_To_Byte_Array(args.PRCR_NO)
        };

        // 콤보 박스의 응답 데이터를 가져옴
        List<string> response_Data = InvokeRequired
            ? (List<string>)Invoke(new Func<List<string>>(Res_CBBOX_Str_Value))
            : Res_CBBOX_Str_Value();

        // 클라이언트에 응답 데이터를 비동기적으로 전송
        await cls_Socket_Server.Process_Response_Data(args.handle, process_Received_Data, response_Data);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }
}
  • 이벤트 핸들러: cls_Socket_Server_Received_Data_And_Sned_Response_Data_Event는 이벤트가 발생했을 때 호출되는 메서드입니다. 이 핸들러는 수신된 데이터를 UI 요소에 표시하고 필요한 데이터를 처리한 후 클라이언트에게 응답을 전송합니다.

요약 (내가 만든 프로그램 기준)

  • 델리게이트는 이벤트가 발생할 때 호출할 메서드의 형식을 정의합니다.
  • 이벤트는 특정 조건이 만족될 때 발생하며, 연결된 이벤트 핸들러를 호출합니다.
  • 이벤트 핸들러는 이벤트가 발생했을 때 실행되는 메서드로, 수신된 데이터를 UI에 표시하고 추가적인 처리를 수행합니다.

 

'(신)회사 > 개인 공부' 카테고리의 다른 글

ref 와 out 차이  (4) 2025.02.05
델리게이트 (delegate)  (2) 2024.11.07