블로그 이미지
따시쿵

calendar

1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30

Notice

2015. 6. 1. 17:28 C#

프로그램 설명


이벤트와 델리게이트에 간단한 예제입니다.


1. 이벤트란?


1. A mechanism for communication between objects.

2. Used in building Loosely Coupled Applications.

   Encodo C# Handbook 7.30 – Loose vs. Tight Coupling

3. Helps Extending Applications.


오브젝트간에 통신(신호)을 담당하는 부분이며 Loosely Coupled 이 가장 큰 특징입니다.

 

 

델리게이트란?

 

1. Agreement / Contract between Publisher and Subscriber

2. Determines the signature of the event handler method in Subscriber

 

 

델리게이트와 이벤트를 만드는 순서


1. Define a delegate

2. Define an event based on that delegate 

3. Raise the event


2. 예제 시나리오를 위해서 3개의 클래스를 미리 만들어 두고, 여기에 델리게이트와 이벤트를 추가하는 것으로 하겠습니다.

 

전체적인 그림은 다음과 같으며, 기본 프로그램에 추가해 보도록 하겠습니다. 

 

기본 소스 파일 :

 

MainForm.cs MainForm.Designer.cs MainForm.resx Video.cs VideoEncoder.cs

 

mainform class

    public partial class MainForm : Form
    {
        public MainForm()
        {
            InitializeComponent();

            Thread t_handler = new Thread(WorkingThread);
            t_handler.IsBackground = true;
            t_handler.Start();
        }

        private void WorkingThread()
        {
            var video = new Video() { Title = "video 1" };
            var videoEncoder = new VideoEncoder();

            videoEncoder.Encode(video, textBox1);
        }
    }

 

Video class

    public class Video
    {
        public string Title { get; set; }
    }

 

VideoEncoder class

    public class VideoEncoder
    {
        private delegate void SetDisplayText(string displayText, TextBox textbox1);
        public void Encode(Video video, TextBox textbox1)
        {
            TextDisplay("Encoding video...\n", textbox1);
            Thread.Sleep(3000);
            TextDisplay("End.", textbox1);
        }

        private void TextDisplay(string displayText, TextBox textbox1)
        {
            if(textbox1.InvokeRequired)
            {   
                textbox1.Invoke(new SetDisplayText(TextDisplay), displayText, textbox1);
                Application.DoEvents();
                return;
            }
            else
            {
                textbox1.AppendText(displayText + "\n");
            }
        }
    }

 

3. 델리게이트와 이벤트를 VideoEncoder class 에 정의합니다. (Publisher 정의)

    public class VideoEncoder
    {
        private delegate void SetDisplayText(string displayText, TextBox textbox1);

        // 1. Define a delegate
        // 2. Define an event based on that delegate
        // 3. Raise the event
        public delegate void VideoEncodedEventHandler(object sender, EventArgs args, TextBox textbpx1);
        public event VideoEncodedEventHandler VideoEncoded;

        public void Encode(Video video, TextBox textbox1)
        {
            TextDisplay("Encoding video...\n", textbox1);
            Thread.Sleep(3000);

            OnVideoEncoded(textbox1);

            TextDisplay("End.", textbox1);
        }

        private void TextDisplay(string displayText, TextBox textbox1)
        {
            if(textbox1.InvokeRequired)
            {   
                textbox1.Invoke(new SetDisplayText(TextDisplay), displayText, textbox1);
                Application.DoEvents();
                return;
            }
            else
            {
                textbox1.AppendText(displayText + "\n");
            }
        }
    }

 

이벤트를 호출합니다.

        protected virtual void OnVideoEncoded(TextBox textbox1)
        {
            if (VideoEncoded != null)
                VideoEncoded(this, EventArgs.Empty, textbox1);
        }

 

 

4. 이벤트 핸들러 구현합니다.(Subscriber 정의)

    public class MailService
    {
        public void OnVideoEncoded(object sender, EventArgs e, TextBox textbox1)
        {
            textbox1.Invoke((MethodInvoker)delegate
            {
                textbox1.AppendText("MailService: Sending an email....\n");
            });
        }
    }

    public class MessageService
    {
        public void OnVideoEncoded(object sender, EventArgs e, TextBox textbox1)
        {
            textbox1.Invoke((MethodInvoker)delegate
            {
                textbox1.AppendText("MessageService: Sending an message text....\n");
            });
        }
    }

 

5. 이벤트와 이벤트 핸들러를 추가합니다. (매개체 역할)  

            var video = new Video() { Title = "video 1" };
            var videoEncoder = new VideoEncoder();      // publisher
            var mailService = new MailService();        // subscriber
            var messageService = new MessageService();  // subscriber

            videoEncoder.VideoEncoded += mailService.OnVideoEncoded;
            videoEncoder.VideoEncoded += messageService.OnVideoEncoded;

            videoEncoder.Encode(video, textBox1);


현재까지 작업한 소스 파일 : MyEvnetnDelegate1.zip


6. 파라미터를 encapsulation 시켜서 구현하는 방법입니다.


파라미터를 숨길 VideoEventArgs class 를 추가 합니다.

    public class VideoEventArgs : EventArgs
    {
        public Video Video { get; set; }
    }

기존의 델리게이트 정의 부분의 두 번째 파라미터를 아래와 같이 VideoEventArgs class 로 변경합니다.


변경 전

public delegate void VideoEncodedEventHandler(object sender, EventArgs args, TextBox text1);

변경 후

public delegate void VideoEncodedEventHandler(object sender, VideoEventArgs args, TextBox text1);


이벤트를 호출하는 부분도 변경해 줍니다.


기존에 EventArgs 를 파라미터로 받는 부분을 VideoEventArgs 로 변경을 해 줍니다.


소스 파일 : 

MyEvnetnDelegate1(2).zip


7.EventHandler<TEventargs> 를 이용한 델리게이트


이벤트에서 이벤트 데이터를 생성할 때 EventHandler<TEventArgs>을 사용하면 사용자 지정 대리자를 직접 코딩할 필요가 없습니다. 단순히 이벤트 데이터 개체의 형식을 제네릭 매개 변수로 제공합니다.


VideoEventArgs class 를 다음과 같이 변경합니다.

    public class VideoEventArgs : EventArgs
    {
        public Video Video { get; set; }
        public TextBox Textbox1 { get; set; }
    }


다음 줄을 삭제합니다.

public delegate void VideoEncodedEventHandler(object sender, EventArgs args, TextBox text1);
public event VideoEncodedEventHandler VideoEncoded;


EventHanlder<TEventArgs> 델리게이트를 추가합니다.

public event EventHandler VideoEncoded;


소스 파일 : 

MyEvnetnDelegate1(3).zip



실행 화면





'C#' 카테고리의 다른 글

람다식(Lambda Expression) - 1  (0) 2015.06.08
EventHandler 와 EventHandler<TEventArgs> Delegate  (0) 2015.06.04
초단위 시간 경과 보이기  (0) 2015.05.12
로그인 창  (0) 2015.05.08
멀티플(multiple) 윈도우 - 2  (0) 2015.05.07
posted by 따시쿵