티스토리 뷰

C#/C# 강좌 Winform

Doridori C# 강의) 26.Thread

꼬꼬마도리도리 2018. 12. 25. 20:01

======================================================

안녕하세요 Doridori 입니다. 


이번 강의는 Thread에 대한 강의 입니다. 


이번강의는 조금 오래 걸렸는데 일정에 맞춰서 진행 하고 있다가 애가 아파서 병원에 있었습니다. ^^ 


자료는 열심히 준비 했습니다. 


약간 이때까지 했던 내용들을 틈틈히 끼워 놓은 느낌의 예제라 한번 보시면 좋을것 같습니다. 


다들 추운 겨울 감기 조심 하세요.

======================================================


Thread


Source UI) Study_26_Thread(UI).zip

Soruce 전체) Study_26_Thread.zip

교재) 26강 Thread.pdf









이번강의는 Thread에 대한 강의 입니다. 


이때까지 보통 Timer를 써서 동작 하거나 작업량이 많은 함수를 실행 했을 경우 화면이 먹통이 되는 느낌을 받거나 작업이 완료 될때까지 다른 동작을 수행 할 수 없는 상황을 많이 보셨을 텐데 이때 문제를 해결하기 위해서 사용하는것이 Thread 라고 보시면 될것 같습니다. 


작업량이 많은 프로그램이라면 빠질수 없는 내용이기 때문에 실무에서 사용하는 프로그램에는 무조건 들어간다고 생각 하시면 됩니다. 


여러개의 작업을 동시에 수행 하기 때문에 어려 작업들이 하나의 자원에 접근한다던지 프로그램이 종료되었지만 여러곳에서 실행 중인 자원이 계속 남아 있다던지 하는 문제가 발생 하기 때문에 Thread의 경우 사용보다는 자원의 관리가 훨씬 더 중요하다고 생각 하시면 될것 같습니다. 


이번 강의에서는 아래 있는 표에서 Start, Sleep 정도만 사용 하였고 (분량이 길어져서 다음강의로 미뤘습니다.)


 나머지의 경우 다 자원의 관리 및 회수에 사용되는데 다음강의에 마저 다룰 예정입니다. 



이번 예제는 원래 프로그램 Loading 시에 주로 다루게 되는 Progressbar를 주제로 준비를 해봤습니다. (일단은 Winform 강좌라서 새로운 Control 하나씩을 목표로 하고 있습니다. ㅎ)


Form Loading 만 하기에는 뭔가 심심한 느낌이어서 다중 Form을 호출 하면서 Thread도 사용하고 지난시간에 진행 했던 delegate도 함께 사용하는 예제를 준비해 보았습니다. 


복습도 하는 느낌으로 따라 오시면 좋을 것 같습니다.







강의)


Thread의 내용이 길어질 것 같아서 UI 부분만 먼저 진행 하고 Source 부분을 따로 진행 했는데 그래도 길어지는 느낌이어서 Thread를 종료하는 부분은 다음강의로 넘기게 되었습니다. 


준비해 놓은게 있으니 다음강의는 빠른시간에 준비 하도록 하겠습니다. ^^


(바빠서~ 아파서~ 라임을 맞추는 느낌으로 말한건데 다시 들어보니 전혀 아니네요 =0=;;)


Thread (1) (UI) )





Thread (2) (Source))





Source)


SubForm이나 추가 Class를 사용하게 되면 항상 느끼는 거지만 Source가 왔다 갔다 해서 헷갈릴수 있는데 천천히 따라 하시면 그리 길지 않은 코드기 때문에 충분히 따라오실수 있을거라고 생각 합니다. 


Main Form )


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace _26_Thread
{
    public partial class Form1 : Form
    {
        private enum enumPlayer
        {
            아이린,
            슬기,
            웬디,
            조이,
            예리,
        }
 
        int _locationX = 0;
        int _locationY = 0;
 
        public Form1()
        {
            InitializeComponent();
 
            _locationX = this.Location.X;
            _locationY = this.Location.Y;
        }
 
        private void btnStart_Click(object sender, EventArgs e)
        {
            _locationX = this.Location.X + this.Size.Width;
            _locationY = this.Location.Y;
 
            for (int i = 0; i < numPlayerCount.Value; i++)
            {
                Play pl = new Play(((enumPlayer)i).ToString());
                pl.Location = new Point(_locationX, _locationY + pl.Height * i);
                pl.eventdelMessage += Pl_eventdelMessage;
 
                pl.Show();
 
                pl.fThreadStart();
            }
 
           
        }
 
        private int Pl_eventdelMessage(object sender, string strResult)
        {
            if (this.InvokeRequired)   // 요청 한 Thread가 현재 Main Thread 있는 Contorl을 엑세스 할 수 있는지 확인
            {
 
                this.Invoke(new Action(delegate ()
                {
 
                    Play oPlayerForm = sender as Play;
 
                    lboxResult.Items.Add(string.Format("Player : {0}, Text : {1}", oPlayerForm.StrPlayerName, strResult));
                }));
 
            }
 
            return 0;
        }
    }
}
 
cs



Sub Form (Play))


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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace _26_Thread
{
    public partial class Play : Form
    {
        public delegate int delMessage(object sender, string strResult);  // delgate 선언
        public event delMessage eventdelMessage;
 
 
        string _strPlayerName = string.Empty;
        public string StrPlayerName { get => _strPlayerName; set => _strPlayerName = value; }
 
        Thread _thread = null;
 
        
 
        public Play()
        {
            InitializeComponent();
        }
 
        public Play(string strPlayerName)
        {
            InitializeComponent();
 
            lblPlayerName.Text = StrPlayerName = strPlayerName;
        }
 
        public void fThreadStart()
        {
            //_thread = new Thread(new ThreadStart(Run));   // ThreadStart 델리게이트 타입 객체를 생성 후 함수를 넘김
 
            _thread = new Thread(Run);   // 컴파일러에서 델리게이트 객체를 추론해서 생성 후 생성 후 함수를 넘김 (new ThreadStart 생략)
 
            //_thread = new Thread(delegate () { Run(); });   // 익명메소드를 사용하여 생성 후 함수를 넘김
 
            _thread.Start();
        }
 
 
        private void Run()
        {
            // UI Control이 자신이 만들어진 Thread가 아닌 다른 Thread에서 접근할 경우 Cross Thread가 발생
            //CheckForIllegalCrossThreadCalls = false;   // Thread 충돌에 대한 예외 처리를 무시 (Cross Thread 무시)
 
            int ivar = 0;
 
            Random rd = new Random();
 
            while (pbarPlayer.Value < 100)
            {
                if (this.InvokeRequired)   // 요청 한 Thread가 현재 Main Thread 있는 Contorl을 엑세스 할 수 있는지 확인
                {
                    this.Invoke(new Action(delegate ()
                    {
 
 
                        //함수값
                        ivar = rd.Next(1, 11);
                        //pbarPlayer.Value = ()
                        if (pbarPlayer.Value + ivar > 100)
                        {
                            pbarPlayer.Value = 100;
                        }
                        else
                        {
                            pbarPlayer.Value = pbarPlayer.Value + ivar;
                        }
 
                        lblProcess.Text = string.Format("진행 상황 표시 : {0}%", pbarPlayer.Value);
 
                        this.Refresh();
 
 
                    }));
 
                    Thread.Sleep(300);
                }
            }
 
            eventdelMessage(this, "완주!! (Thread Complete)");
        }
        
    }
}
 
cs


댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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 31
글 보관함