반응형

BackgroundWorker 클래스를 사용 하면 별도 전용 스레드에서 작업을 실행할 수 있습니다. 다운로드 및 데이터베이스 트랜잭션과 같은 시간이 많이 걸리는 작업은 사용자 인터페이스 (UI) 실행 하 고 응답을 멈춘 것 처럼 보일 수 발생할 수 있습니다. 이러한 작업으로 인 한 지연이 길어지는 경우 및 응답성이 뛰어난 UI를 구성할 때의 BackgroundWorker 클래스는 편리 하 게 솔루션을 제공 합니다.

시간이 많이 걸리는 작업을 백그라운드에서를 실행 하려면 만들기를 BackgroundWorker 작업이 완료 되 면 신호 확인 하 고 작업의 진행률을 보고 하는 이벤트를 수신 합니다. 만들 수 있습니다는 BackgroundWorker 프로그래밍 방식으로에서 폼으로 끌어 놓을 수 있습니다 합니다 구성 요소 탭의 도구 상자. 만드는 경우는 BackgroundWorker Windows Forms 디자이너에서 구성 요소 트레이에 표시 됩니다 하 고 해당 속성이 속성 창에 표시 됩니다.

백그라운드 작업에 대 한 설정에 대 한 이벤트 처리기를 추가 합니다 DoWork 이벤트입니다. 이 이벤트 처리기에서 시간이 오래 걸리는 작업을 호출 합니다. 작업을 시작 하려면 호출 RunWorkerAsync합니다. 진행률 업데이트의 알림을 받으려면 처리는 ProgressChanged 이벤트입니다. 작업이 완료 될 때 알림을 받으려면 처리는 RunWorkerCompleted 이벤트입니다.

 

Background Worker 속성

BackgroundWorker 이벤트

 

예제

다음 코드 예제는 기본 사항을 보여줍니다는 BackgroundWorker 시간이 많이 걸리는 작업을 비동기적으로 실행 하기 위한 클래스입니다. 다음 그림에서는 출력의 예를 보여 줍니다.

 

이 코드를 실행 하려면 Windows Forms 애플리케이션을 작성 합니다. 추가 Label 라는 컨트롤 resultLabel 두 개의 추가 Button 컨트롤 이라는 startAsyncButton  cancelAsyncButton합니다. 만들 Click 두 단추에 대 한 이벤트 처리기입니다. 구성 요소 탭 도구 상자의 추가 BackgroundWorker 라는 구성 요소 backgroundWorker1합니다. 만들 DoWork, ProgressChanged, 및 RunWorkerCompleted 에 대 한 이벤트 처리기는 BackgroundWorker합니다. 폼의 코드에서 기존 코드를 다음 코드로 바꿉니다.

 

 

Imports System.Windows.Forms

Public Class Form1

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.WorkerSupportsCancellation = True
    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        If BackgroundWorker1.IsBusy <> True Then
            ' 백그라운드 스레드 시작
            BackgroundWorker1.RunWorkerAsync()
        End If
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        If BackgroundWorker1.WorkerSupportsCancellation = True Then
            ' 백그라운드 스레드 취소
            BackgroundWorker1.CancelAsync()
        End If
    End Sub

    '스레드 동작 구문
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As System.ComponentModel.BackgroundWorker = CType(sender, System.ComponentModel.BackgroundWorker)
        Dim i As Integer
        For i = 1 To 10 Step i + 1
            If worker.CancellationPending = True Then
                e.Cancel = True
                Exit For
            Else
                ' Perform a time consuming operation and report progress.
                System.Threading.Thread.Sleep(500)
                worker.ReportProgress(i * 10)
            End If
        Next
    End Sub

    '라벨 디스플레이 업데이트
    Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As System.Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
        resultLabel.Text = (e.ProgressPercentage.ToString() + "%")
    End Sub

    '백그라운드 워커 컨트롤 상태 표시
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        If e.Cancelled = True Then
            resultLabel.Text = "Canceled!"
        ElseIf Not e.Error Is Nothing Then
            resultLabel.Text = "Error: " + e.Error.Message
        Else
            resultLabel.Text = "Done!"
        End If
    End Sub
End Class

 

*참고 : https://docs.microsoft.com/ko-kr/dotnet/api/system.componentmodel.backgroundworker?view=netframework-4.8

 

[C#] 백그라운드 스레드(BackGround Worker Class)

 

[C#] 백그라운드 스레드(BackGround Worker Class)

BackgroundWorker 클래스를 사용 하면 별도 전용 스레드에서 작업을 실행할 수 있습니다. 다운로드 및 데이터베이스 트랜잭션과 같은 시간이 많이 걸리는 작업은 사용자 인터페이스 (UI) 실행 하 고 응답을 멈춘..

kdsoft-zeros.tistory.com

 

반응형
반응형

* 크로스 스레드

 - 자신의 스레드가 아닌 다른 스레드가 그 컨트롤에 접근 했을 때 나는 오류 

 

 

*해결 방법 예제

 

 

Form1.vb

 

Public Class Form1

    '   스레드의 동작을 제어하는 메서드 
    '   Abort():강제 종료 
    '   Interrupt():대기 중인 스레드를 중단 
    '   Join(): 스레드가 종료될 때까지 호출 스레드를 차단 
    '   Sleep(int millisecondsTimeout): 지정된 시간(밀리초)동안 스레드를 중지 
    '   Start(): 스레드 시작 
    '   Suspend(): 일시 중지 
    '   Resume(): 일시 중지된 스레드 수행 

    Dim thMain As Threading.Thread
    Dim bThread As Boolean = False

    '최초 한번만 실행...
    Dim bThreadStart As Boolean = False

#Region "2번째 방법..."
    '델리게이트 선언...
    Delegate Sub TextBoxDelegate(ByVal strText As String)
    '델리게이트를 위한 함수 선언...
    Private Sub TextBoxFunc(ByVal strText As String)
        txtThread.Text = strText
    End Sub

#End Region

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        '1번째 해결 방법...
        'CheckForIllegalCrossThreadCalls = False

        thMain = New Threading.Thread(New Threading.ThreadStart(AddressOf Thread_Timer))

        '스레드를 백그라운드로 지정...
        '기본 : 포어그라운드 차이점 => 프로그램 종료시 백그라운드 스레드는 하던일 멈추고 같이 종료...
        '포어그라운드 스레드는 하던일 다 하고 나면 종료...
        thMain.IsBackground = True
        
    End Sub

    Private Sub Form1_FormClosed(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosedEventArgs) Handles MyBase.FormClosed
		
        If (thMain Is Nothing) Then

            If (bThreadStart) Then
                thMain.Abort()        '스레드 강제 종료...
            Else
                thMain.Interrupt()    '대기중인 스레드 종료...
            End If
            '스레드 변수에 nothing 대입으로 사용을 안하겠다 표시
            thMain = Nothing
        End If

    End Sub

    Private Sub button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button1.Click

        If (Not bThreadStart) Then   '프로그램 실행시 한번도 스레드가 실행 되지 않았음으로 최초 한번 실행...
            bThread = True
            bThreadStart = True
            thMain.Start()                     '스레드 시작
        Else   '일시 정지일 경우 다시 실행...
            bThread = True
            thMain.Resume()                    '일시 정지된 스레드 다시 시작
        End If

    End Sub

    Private Sub button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles button2.Click
        bThread = False
        thMain.Suspend()                       '스레드 일시 정지...
    End Sub


    Sub Thread_Timer()

        While (bThread)

            '크로스 스레드 오류 내기...
            'txtThread.Text = "크로스 스레드 예제..."

            '2번째 방법 사용
            Me.Invoke(New TextBoxDelegate(AddressOf TextBoxFunc), "크로스 스레드 예제...")

            Threading.Thread.Sleep(1000)

        End While

    End Sub

    
End Class

위 소스 예제를 보시는 바와 같이 1,2번째 방법 으로 예제를 만들어 보았습니다.

 

*요약

 

[VBNET] 델리 게이트 (Delegate) - 델리게이트란? , 선언 방법과 간단한 예제

 

[VBNET] 델리 게이트 (Delegate) - 델리게이트란? , 선언 방법과 간단한 예제

*델리 게이트(Delegate) - 대리자 로써 C 언어나 C++ 언어 를 공부한 사람이라면 쉽게 접할 수 있는 함수 포인터와 비슷한 기능을 합니다. 또한 콜백 함수 기능 역할도 수행 *델리 게이트 선언 방법과 간단한 예제..

kdsoft-zeros.tistory.com

[C#] 크로스 스레드 (Cross Thread) 예제

 

[C#] 크로스 스레드 (Cross Thread) 예제

* 크로스 스레드 - 자신의 스레드가 아닌 다른 스레드가 그 컨트롤에 접근했었을 때 발생하는 오류 * 해결 방법 Form1.cs using System; using System.Collections.Generic; using System.ComponentModel; using..

kdsoft-zeros.tistory.com

 

반응형
반응형

* 크로스 스레드

 - 자신의 스레드가 아닌 다른 스레드가 그 컨트롤에 접근했었을 때 발생하는 오류

    

* 해결 방법

 

Form1.cs 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Threading;

namespace CrossThread
{
    public partial class Form1 : Form
    {

        /* 
       스레드의 동작을 제어하는 메서드 
       Abort():강제 종료 
       Interrupt():대기 중인 스레드를 중단 
       Join(): 스레드가 종료될 때까지 호출 스레드를 차단 
       Sleep(int millisecondsTimeout): 지정된 시간(밀리초)동안 스레드를 중지 
       Start(): 스레드 시작 
       Suspend(): 일시 중지 
       Resume(): 일시 중지된 스레드 수행 
       */

        Thread thMain;
        bool bThread = false;

        //스레드 최초 한번 실행...
        bool bThreadStart = false;


        #region 3번째 방법...
        //3번째  방법 델리게이트 선언...
        delegate void TextBoxDelegate(string strText);
        //3번째  방법 델리게이트를 위한 함수 선언...
        private void TextBoxFunc(string strText)
        {
            txtThread.Text = strText;
        }
        #endregion

        public Form1()
        {
            InitializeComponent();

            //1. 첫번째 해결 방법 
            //CheckForIllegalCrossThreadCalls = false ;

            thMain = new Thread(new ThreadStart(Thread_Timer));
            thMain.IsBackground = true;                            //스레드를 백그라운드로 지정...
                                                                   //기본 : 포어그라운드 차이점 => 프로그램 종료시 백그라운드 스레드는 하던일 멈추고 같이 종료...
                                                                   //                                              포어그라운드 스레드는 하던일 다 하고 나면 종료...
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            //스레드 종료...
            if (thMain != null)
            {
                if (bThreadStart)
                {
                    thMain.Abort();    //강제 종료...
                }
                else
                {
                    thMain.Interrupt(); //대기중인 스레드 종료...
                }
                
                thMain = null;
            }
        }

        //버튼 이벤트...
        private void button1_Click(object sender, EventArgs e)
        {
            //최초 한번만 실행...
            if (!bThreadStart)
            {
                bThread = true;
                bThreadStart = true;
                thMain.Start();
            }
            //일시정지...
            else
            {
                bThread = true;
                thMain.Resume ();
            }
            
        }
        private void button2_Click(object sender, EventArgs e)
        {
            if(bThreadStart)
            {
                 bThread = false;
            	 //일시 정지 된 스레드 다시 실행...
            	 thMain.Suspend ();  
            }
        }

        void Thread_Timer()
        {
            while (bThread)
            {

                try
                {
                    //크로스 스레드 오류 내기...
                    //txtThread.Text = "크로스 스레드 예제...";

                    //2번째 방법...
                    /*
                    if (txtThread.InvokeRequired == true)
                    {
                        //다른 스래드이다...
                        this.Invoke(new Action(delegate()
                        {
                            txtThread.Text = "크로스 스레드 예제...";
                        }));
                    }
                    else
                    {
                        //같은 스래드이다...
                        txtThread.Text = "크로스 스레드 예제...";
                    }
                     */

                    //3번째 방법으로 사용 예제
                    this.Invoke(new TextBoxDelegate(TextBoxFunc), "크로스 스레드 예제...");


                }
                catch (Exception ex)
                {
                    MessageBox.Show("오류 : " + ex.Message.ToString());
                }
                

                Thread.Sleep(1000);
            }
        }

    }
}

 

위 소스 예제를 보시는 바와 같이 1,2,3 번째 방법 으로 예제를 만들어 보았습니다.

* 요약

[C#] 델리 게이트 (Delegate) - 1 델리게이트란? , 선언 방법과 간단한 예제

 

[C#] 델리 게이트 (Delegate) - 1 델리게이트란? , 선언 방법과 간단한 예제

*델리 게이트(Delegate) - 대리자 로써 C 언어나 C++ 언어 를 공부한 사람이라면 쉽게 접할 수 있는 함수 포인터와 비슷한 기능을 합니다. 또한 콜백 함수 기능 역할도 수행 *델리 게이트 선언 방법과 간단한 예제..

kdsoft-zeros.tistory.com

[C#] 델리 게이트 (Delegate) - 2 델리게이트 콜백과 사용 그리고 체인

 

[C#] 델리 게이트 (Delegate) - 2 델리게이트 콜백과 사용 그리고 체인

앞서 간략 하게 델리게이트가 무엇이며 선언 방법과 사용은 어떻게 하는지 알아 보았습니다. 하지만 사용 방법에 있어 왜 굳이 델리게이트를 사용하지 그냥 함수를 호출 하면 되지 않을까? 그게 더 효율적이지 싶..

kdsoft-zeros.tistory.com

 

반응형
반응형

C# Indexer는  클래스 속성(Property)에 특별한 문법인 this[ ] 를 써서 클래스 내부의 어떤 데이타를 셋팅 및 리턴을 받을 수 있게 만드는 똑똑한 배열이라고 볼 수 있습니다.

 

* 예제

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Indexer2
{
    class IndexerClass
    {
        //배열 크기 기본 10
        private const int index_MAX = 10;

        // 내부의 정수 배열 
        private int[] idata = new int[index_MAX];

        // 인덱서 정의. 
        public int this[int index]
        {
            get
            {
                if (index < 0 || index >= index_MAX)
                {
                    throw new IndexOutOfRangeException();
                }
                else
                {
                    // 배열로부터 값 리턴
                    return idata[index];
                }
            }
            set
            {
                if (!(index < 0 || index >= index_MAX))
                {
                    // 배열에 값 저장
                    idata[index] = value;
                }
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            IndexerClass icls = new IndexerClass();

            // 인덱서 set 사용
            icls[1] = 3096000;

            // 인덱서 get 사용
            int iValue = icls[1];

            //값 확인
            System.Console.WriteLine(iValue.ToString());
            System.Console.WriteLine("Press the Enter key to continue.");
            System.Console.ReadLine();
        }
    }
}

 

 

위의 예제와 같이 클래스 내부에 정수형 배열 선언과 클래스 속성에 인덱서를 정의 하여 마치 클래스 속성을

배열 처럼 사용 하여 보았습니다.

이번에는 제네릭과 인덱서를 같이 활용한 예제를 만들어 보겠습니다.

 

- 제네릭 클래스

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Indexer
{
    class Indexer<T>
    {
        //T 제네릭 : 데이터 자료형에 관한 것...Ex) int, byte, String, float, double 형 등등 

        public T[] Items;

        #region 생성자...
        //기본 인덱서 클래스 내 아이템 변수 10개...
        public Indexer()
        {
            Items = new T[10];
        }
        //사용자가 직접 크기 결정...
        public Indexer(int iSize)
        {
            Items = new T[iSize];
        }
        #endregion

        #region 속성...
        //인덱서 정의...
        public T this[int index]
        {
            get
            {
                return Items[index];
            }
            set
            {
                Items[index] = value;
            }
        }

        public int FnLength
        {
            get
            {
                return Items.Length;
            }
        }

        #endregion

    }
}

- 폼 메인화면

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Indexer
{
    public partial class Form1 : Form
    {
        Indexer<int> idList_int = new Indexer<int>();
        Indexer<string> idList_Str = new Indexer<string>();

        List<int> ltList_int = new List<int>();

        public Form1()
        {
            InitializeComponent();

            for (int iCount = 0; iCount < idList_int.FnLength; iCount++)
            {
                //인덱서를 활용한 Array 
                idList_int[iCount] = iCount + 1;
                idList_Str[iCount] = (iCount + 1).ToString() + "Str";

                //Array 계열 List 사용
                ltList_int.Add(iCount + 1);
            }

        }

        private void button1_Click(object sender, EventArgs e)
        {
            listBox1.Items.Clear();
            listBox2.Items.Clear();

            for (int iCount = 0; iCount < idList_int.FnLength; iCount++)
            {
                listBox1.Items.Add(idList_int[iCount]);              //인덱서클래스 int 형 
                listBox2.Items.Add(idList_Str[iCount]);              //인덱서클래스 string 형
            }

            listBox1.Items.Add("========================================================");

            for (int jCount = 0; jCount < ltList_int.Count; jCount++)
            {
                listBox1.Items.Add(ltList_int[jCount]);             //List 배열
            }


        }
    }
}

 

위 예제에서 보듯이 제네릭과 인덱서를 같이 활용하면 List 배열 처럼 사용 할 수 있습니다.

다만 List 배열과 가장 큰 차이점은 배열의 크기가 정해지느냐 안 정해지느냐 로 볼 수 있습니다.

반응형
반응형

*델리 게이트(Delegate)

 - 대리자 로써 C 언어나 C++ 언어 를 공부한 사람이라면 쉽게 접할 수 있는 함수 포인터와

   비슷한 기능을 합니다.  또한 콜백 함수 기능 역할도 수행 

   

*델리 게이트 선언 방법과 간단한 예제

 

Public Class Form1

    '델리 게이트 선언...
    Delegate Function delegateFuncA(ByVal a As Integer, ByVal b As Integer) As Integer
    Delegate Sub delegateFuncB(ByVal a As Integer, ByVal b As Integer)
    Delegate Function delegateFuncC(ByVal a As Integer) As String


    '폼 버튼 이벤트...
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        'FuncA 함수에 대한 델리게이트 초기화
        Dim dfa As delegateFuncA = New delegateFuncA(AddressOf FuncA)
        MessageBox.Show(dfa(5, 6).ToString() + " , Delegate 함수 사용")

    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        'FuncB 함수에 대한 델리게이트 초기화
        Dim dfa As delegateFuncB = New delegateFuncB(AddressOf FuncB)
        dfa(5, 6)
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        'FuncC 함수에 대한 델리게이트 초기화
        Dim dfa As delegateFuncC = New delegateFuncC(AddressOf FuncC)
        MessageBox.Show(dfa(5))
    End Sub

    '폼 내부 함수들...
    Private Function FuncA(ByVal a As Integer, ByVal b As Integer) As Integer
        Return a + b
    End Function

    Private Sub FuncB(ByVal a As Integer, ByVal b As Integer)
        MessageBox.Show((a + b).ToString())
    End Sub

    Private Function FuncC(ByVal a As Integer) As String
        Return (a + 15).ToString()
    End Function

End Class

위 코드와 같이 델리 게이트 선언 형식과 함수 형식이 같으며,

(델리게이트 함수 이름은 변수 이름(delegateFuncA,B,C) 사용자 마음대로 지정 가능)

만약 리턴 형식 및 전달 인자 형식이 틀리게 되면 아래의 그림과 같이 오류가 발생 하게 됩니다.

 

간략히 델리 게이트가 무엇이며, 간단한 예제를 만들어 봤습니다.

 

* C# 델리 게이트 (Delegate) -  1 델리게이트란? , 선언 방법과 간단한 예제

https://kdsoft-zeros.tistory.com/18

반응형
반응형

앞서 간략 하게 델리게이트가 무엇이며 선언 방법과 사용은 어떻게 하는지 알아 보았습니다.

하지만 사용 방법에 있어 왜 굳이 델리게이트를 사용하지 그냥 함수를 호출 하면 되지 않을까?

그게 더 효율적이지 싶은데... 라는 의문도 생기실 수 있으실 겁니다. 

이번 시간에는 좀 더 그런 의문을 없애기 위해 델리게이트가 어떻게 사용 되는지를 알아보

겠습니다.

 

* 델리게이트 콜백

 - 내 함수를 줄테니 다시 되돌려줘 !!! 꼬옥 !!!

 

그림에서 보는 거와 같이 버튼을 클릭하여 클래스 이벤트를 발생 시키는 예제를 만들어 보았습니다.

이렇게 이미지로만 본다면 그냥 버튼 두개에 메시지 박스 뜨네 라고 생각 하실 수도 있겠습니다. 

Form1 메인 소스

 

위 소스와 같이 버튼을 클릭 했는데 Form 에 있는 Start 함수 End 함수를 직접 실행 하지 않았습니다. 

다만 Form 을 시작 할때 클래스를 초기화 하고 클래스 안에 선언되어있는 델리게이트에 

Form 에 선언한 Start(), End() 두 함수를 던져 주었을 뿐...

그리고 나서 클래스 이벤트에 그 델리게이트가 연결 되어 있습니다.

 

위 그림에서 보시는 거와 같이 클래스 에 델리게이트가 선언이 되어 있으며, 이벤트도 발생 하게 되어 있습니다.

Form 시작하기에 앞서 클래스 초기화를 했고 클래스에 선언된 델리게이트에 Form 내부 함수를 던져 주었으며,

그 델리게이트를 클래스 이벤트에 등록 하였습니다. 사용자가 버튼을 클릭 시 클래스 함수 Start() 와 End() 함수

를 실행 하게 되는데 각각 이벤트를 발생 시키는 코드를 가지고 있습니다.

 

이벤트가 발생이 되면 다시 Form에 있는 Start() End() 함수가 실행 되어 메시지 박스 그림을 보게 됩니다.

 

이와 같이 Form 함수를 넘겨주어 다시 되돌려 받는 델리게이트 콜백 및 사용 방법 이였습니다.

 

* 델리게이트 체인 : 하나의 델리게이트에 여러 개의 함수를 연결 시키는 것

[예제]
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{

    delegate void OneDelegate(int a, int b);

    class Program
    {

        public static void Plus(int a, int b)
        {
            Console.WriteLine("{0} + {1} = {2}", a, b, a + b);
        }

        public static void Minus(int a, int b)
        {
            Console.WriteLine("{0} - {1} = {2}", a, b, a - b);
        }

        public static void Multiplication(int a, int b)
        {
            Console.WriteLine("{0} * {1} = {2}", a, b, a * b);
        }

        public static void Division(int a, int b)
        {
            Console.WriteLine("{0} / {1} = {2}", a, b, a / b);
        }

        static void Main(string[] args)
        {
			//델리게이트 초기화
            OneDelegate m = new OneDelegate(Plus); 
            
            //델리게이트에 함수들 추가
            m += Minus;
            m += Multiplication;
            m += Division;

            m(3,4); //등록된 함수들 실행

            //델리게이트에 등록된 함수 빼기
            m -= Multiplication;
            m -= Division;

            System.Console.WriteLine("=======================================");

            m(3,4);

            System.Console.WriteLine("Press the Enter key to continue.");
            System.Console.ReadLine();


        }
    }
}

[C#] 델리 게이트 (Delegate) - 1 델리게이트란? , 선언 방법과 간단한 예제

 

반응형
반응형

*델리 게이트(Delegate)

 - 대리자 로써 C 언어나 C++ 언어 를 공부한 사람이라면 쉽게 접할 수 있는 함수 포인터와

   비슷한 기능을 합니다.  또한 콜백 함수 기능 역할도 수행 

   

*델리 게이트 선언 방법과 간단한 예제

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Delegate
{
    public partial class Form1 : Form
    {
		//델리게이트 선언...
        delegate int delegateFuncA(int a, int b);
        delegate void delegateFuncB(int a, int b);
        delegate string delefageFuncC(int a);

        public Form1()
        {
            InitializeComponent();
        }
		
        //함수 선언...
        private int FuncA(int a, int b)
        {
            return a + b;
        }
        private void FuncB(int a, int b)
        {
            MessageBox.Show((a + b).ToString());
        }
        private string FuncC(int a)
        {
            return (a + 15).ToString();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            delegateFuncA dfa = new delegateFuncA(FuncA); //FuncA 에 대한 델리게이트를 만든다.
            MessageBox.Show(dfa(5, 6).ToString() + " , Delegate 함수 사용");

        }

        private void button2_Click(object sender, EventArgs e)
        {
            delegateFuncB dfa = new delegateFuncB(FuncB); //FuncB 에 대한 델리게이트를 만든다.
        }

        private void button3_Click(object sender, EventArgs e)
        {
            delefageFuncC dfa = new delefageFuncC(FuncC); //FuncC 에 대한 델리게이트를 만든다.
            MessageBox.Show(dfa(5));
        }
    }
}

 

위 코드와 같이 델리 게이트 선언 형식과 함수 형식이 같으며,

(델리게이트 함수 이름은 변수 이름(delegateFuncA,B,C) 사용자 마음대로 지정 가능)

만약 리턴 형식 및 전달 인자 형식이 틀리게 되면 아래의 그림과 같이 오류가 발생 하게 됩니다.

 

 

간략히 델리 게이트가 무엇이며, 간단한 예제를 만들어 봤습니다. 다음 시간에는 실제 델리게이트가 어떻게 사용

되는지 알아 보는 시간을 갖도록 하겠습니다~

반응형
반응형

#region 프로젝트 폼 목록 읽어 오기

        public static Form GetAssemblyForm(string strFormName)
        {
            Form f = null;
            foreach (Type t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
            {
                if (t.Name == strFormName)                     //프로젝트 내 폼 중에서 찾을 이름과 같으면...
                {
                    object o = Activator.CreateInstance(t);    //인스턴스 개체 생성 
                    f = o as Form;                                  //인스턴스 개체 폼 형식으로 캐스팅
                }
            }
            return f;
        }

        public static List

 GetAssemblyFormList()
        {
            List
 ltForm = new List

();
            foreach (Type t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
            {
                if (t.BaseType.FullName.ToString() == "System.Windows.Forms.Form")  // 타입이 윈도우즈 폼이면...
                {
                    object o = Activator.CreateInstance(t);                                      //개체 생성
                    Form f = o as Form;                                                            //폼 형식으로 캐스팅
                    ltForm.Add(f);                                                                    //리스트에 담기
                }
            }

            return ltForm;

        }

        #endregion

 

 

 

 

소스 예제...

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        #region 프로젝트 폼 목록 읽어 오기

        private Form GetAssemblyForm(string strFormName)
        {
            Form f = null;
            foreach (Type t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
            {
                if (t.Name == strFormName)
                {
                    object o = Activator.CreateInstance(t);
                    f = o as Form;
                }
            }

            return f;

        }

        private List<Form> GetAssemblyFormList()
        {
            List<Form> ltForm = new List<Form>();

            listBox1.Items.Clear();

            foreach (Type t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes())
            {
                if (t.BaseType.FullName.ToString() == "System.Windows.Forms.Form")
                {
                    object o = Activator.CreateInstance(t);
                    Form f = o as Form;
                    ltForm.Add(f);
                }
            }

            return ltForm;

        }

        #endregion


        private void button1_Click(object sender, EventArgs e)
        {
            List<Form> ltList = GetAssemblyFormList();

            for (int iCount = 0; iCount < ltList.Count; iCount++)
            {
                Form f = ltList[iCount] as Form;
                listBox1.Items.Add(f.Text);
            }

        }

        private void button2_Click(object sender, EventArgs e)
        {
            Form f = GetAssemblyForm("frmSearch");

            MessageBox.Show(f.Text + " 를 찾았습니다.");
        }
    }
}

 

반응형

+ Recent posts