티스토리 뷰
======================================================
안녕하세요 Doridori 입니다.
타지에 출장가있는 시기가 길다보니 혼자 생각도 많아지고 이 시간 들을 활용 하고 싶은데 활용은 어렵고, 고민이 많이 되는 시기 인듯 합니다.
이제 앞으로 조금이면 일단은 서울로 복귀를 하고 이후에 다시 일정이 나올것 같기는 한데 이럴때가 가장 어수선한 시기가 아닌가 싶기도 하네요.
블로그를 보시면 알겠지만 요근래 시간이 나면 여행도 많이 다니면서 기분전환도 많이한것 같고, 개인적으로 해보고 싶은것들도 준비하고 하면서 지내고 있습니다.
c# 강좌 말고도 이것저것 하고 있으니 보시다가 머리를 식히시고 싶으시면 여행 리뷰나 술 리뷰 보시면서 머리 식히시고 가셔도 좋을 듯 합니다. ^^v
뭔가 성격상 해보고 싶은건 해봐야 멈출 수 있기 때문에 또 하고 싶은걸 해보도록 하겠습니다. ㅎㅎ
모두 화이팅 하십시오!!
(영상에서 parallel 사용 시 작업 순서가 명확할 때에는 사용하면 안된다고 적어 놓은 부분이 잘못 적었다고 수정해야 한다고 했는데, 이게 잘못된 말이 아니고 작업 순서가 명확해야 할 경우에는 분산처리를 사용하지 않는것이 좋습니다.)
======================================================
60. 분산처리 프로그램 (Parallel)
UI)
Soruce)
교재)
지난번 성능 카운터를 이야기 하면서 이번 강의와 엮어서 준비를 하고 있었는데, 진행을 하다 보니 엮기가 쉽지 않아서 시간만 끌릴것 같아 그냥 따로 준비 해보았습니다.
parallel.for가 처음 나왔을 때 신기술은 바로 사용해야 찐개발이지 라고 하고 사용 했다가 프로그램이 down되서 바로 일반 for문으로 돌렸던 기억이 있어서 조심스러운 느낌이기도 했습니다.
분명히 좋은 기능이지만 잘생각해보고 사용해야 하는것이 아닌가 라는 생각이 많이 드는 기술(?) 이네요 ㅎ
UI)
살짝 급하게 만들다 보니 이것저것 더 넣고 싶었던게 많은데 그래도 나름 나쁘지 않은(?), 하고 싶은 이야기를 충분히 담은 예제를 만들 수 있었던것 같습니다.
진행하면서 예전에 action이나 list 초기화 하는 부분이나 이런 부분들도 한번 다시 짚어 봤으니 나름 재미있게 보실 수 있지 않을까 생각 합니다.
강의)
뭔가 되게 텐션이 높은 상태에서 강의를 준비한것이 아니라 약간 차분한 느낌으로 강의를 만들었던것 같은데 살짝 아쉽긴 하지만 예제를 만들고 바로 강의를 찍어서 내용의 흐름 자체는 만족하면서 진행 했던것 같습니다.
강의 중간에 사용시 주의점을 잘못 말씀 드린 부분이 있긴 한데 (작업 순서를 보장하지 않기 때문에 작업순서가 명확해야 할 경우에는 사용을 지양하는것이 좋습니다.)
나름 재미 있는 기능이 아닐까 싶기는 하네요. ㅎ
Source)
소스를 올리는 부분이 상당히 귀찮기는 한데 이 부분의 경우 다른 분들보다도 구독하시는 분들이 질문을 올려주시면 제가 내용을 확인하는 용도로 많이 사용하기 때문에 안올릴수도 없고 ㅎㅎ
그러다보니 강의용 프로그램을 짤때에는 클래스를 안쪼개는게 습관이 되고 있네요. (별로 좋은것 같지는 않지만. ㅎㅎ;;)
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
|
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace pCounter
{
public partial class Form1 : Form
{
#region Enum
// Case문 관련 enum
enum enCase
{
nfor,
pfor,
pforeach,
pfunction,
}
#endregion
#region
private int _iThreadSleepTime = 10; // Thread Sleep
private int _iforStart = 0; // for Start
private int _iforCount = 100; // for Count
DateTime sTime; // Thread 시작 시간을 가져오기 위함 Function
#endregion
public Form1()
{
InitializeComponent();
}
#region Event
// 일반 For 문
private void btnfor_Click(object sender, EventArgs e)
{
pThread(enCase.nfor);
}
// Parallel For 문
private void btnPararallfor_Click(object sender, EventArgs e)
{
pThread(enCase.pfor); // UI에서 바로 작업 할 경우 Event와 Parallel문의 경우 충돌이 발생 할 확률이 크기 때문에 별도 Thread를 구성해서 동작 하도록 함
}
// Parallel Foreach 문
private void btnParallelforeach_Click(object sender, EventArgs e)
{
pThread(enCase.pforeach);
}
// Parallel function
private void btnParallelFunction_Click(object sender, EventArgs e)
{
pThread(enCase.pfunction);
}
#endregion
#region Main Thread
private void pThread(enCase eCase)
{
sTime = DateTime.Now;
Log(lboxPlayTime, enLogLevel.Info, $"Thread Start");
Thread tCase;
switch (eCase)
{
case enCase.nfor:
tCase = new Thread(fnfor);
tCase.Start();
break;
case enCase.pfor:
tCase = new Thread(fpfor);
tCase.Start();
break;
case enCase.pforeach:
tCase = new Thread(fpforeach);
tCase.Start();
break;
case enCase.pfunction:
tCase = new Thread(fpfunction);
tCase.Start();
break;
default:
break;
}
}
#endregion
#region innerfunction
// 일반 for 문
private void fnfor()
{
for (int i = _iforStart; i < _iforCount; i++)
{
Log(enLogLevel.Info, $"for : {i}");
Thread.Sleep(_iThreadSleepTime);
}
DateTime eTime = DateTime.Now;
Log(lboxPlayTime, enLogLevel.Info, $"Thread End : {eTime - sTime}");
}
// Parallel for 문 (여러 형태로 사용 가능)
private void fpfor()
{
int iTotal = 0;
// 람다식
Parallel.For(_iforStart, _iforCount, i =>
{
//Log(enLogLevel.Info, $"pfor(람다) : {iTotal} + {i} = {iTotal = iTotal + i}"); // 순서를 보장하지 않음
Log(enLogLevel.Info, $"pfor(람다) : {i}");
Thread.Sleep(_iThreadSleepTime);
});
DateTime eTime = DateTime.Now;
Log(lboxPlayTime, enLogLevel.Info, $"Thread End : {eTime - sTime}");
//Parallel.For(_iforStart, _iforCount, pfun);
// 무명메서드
/*
Parallel.For(_iforStart, _iforCount, delegate(int i)
{
Log(enLogLevel.Info, $"pfor(무명) : {i}");
Thread.Sleep(10);
});
*/
/*
// 람다식
Parallel.For(_iforStart, _iforCount, (i) =>
{
Log(enLogLevel.Info, $"pfor(람다) : {i}");
Thread.Sleep(10);
});
*/
}
/*
Action<int> afun = pfun;
public static void pfun(int a)
{
}
*/
// Parallel foreach 문 (배열 선언 후 사용)
private void fpforeach()
{
//List<int> iList = (Enumerable.Repeat(i++, 10)).ToList<int>(); // 선언 하면서 같은 수로 초기화 하는 법
List<int> iList = (Enumerable.Range(_iforStart, _iforCount)).ToList<int>(); // 선언 하면서 순차적으로 값을 넣는 법
Parallel.ForEach(iList, i =>
{
Log(enLogLevel.Info, $"pforeach(람다) : {i}");
Thread.Sleep(_iThreadSleepTime);
});
DateTime eTime = DateTime.Now;
Log(lboxPlayTime, enLogLevel.Info, $"Thread End : {eTime - sTime}");
}
// parallel function (다중 함수 호출)
private void fpfunction()
{
Parallel.Invoke(
fpfor,
fpforeach
);
/*
Parallel.Invoke(
() => { return; },
() => { return; },
() => { return; }
);
*/
}
#endregion
#region Log Viewer
// Log Level을 지정 할 Enum (44강 Tree View 참조)
enum enLogLevel
{
Info,
Warning,
Error,
}
private void Log(enLogLevel eLevel, string LogDesc)
{
this.Invoke(new Action(delegate ()
{
DateTime dTime = DateTime.Now;
string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
lboxLog.Items.Insert(0, LogInfo);
Refresh();
}));
}
private void Log(DateTime dTime, enLogLevel eLevel, string LogDesc)
{
this.Invoke(new Action(delegate ()
{
string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
lboxLog.Items.Insert(0, LogInfo);
}));
}
// List Box Control 추가
private void Log(ListBox lbox, enLogLevel eLevel, string LogDesc)
{
this.Invoke(new Action(delegate ()
{
DateTime dTime = DateTime.Now;
string LogInfo = $"{dTime:yyyy-MM-dd hh:mm:ss.fff} [{eLevel.ToString()}] {LogDesc}";
lbox.Items.Insert(0, LogInfo);
}));
}
#endregion
}
}
|
cs |
'C# > C# 강좌 Winform' 카테고리의 다른 글
Doridori C# 강의 3) 62. 메일 보내기 (send email) (17) | 2022.06.19 |
---|---|
Doridori C# 강의 3) 61. 정규식 (Regular Expression) (4) | 2022.05.06 |
Doridori C# 강의 3) 59. PerformanceCounter (성능 카운터) (4) | 2022.02.04 |
Doridori C# 강의 3) 58. Quartz Scheduler (쿼츠 스케줄러) (1) | 2021.10.03 |
Doridori C# 강의) C# 프로그래밍 무조건 따라하기 (Chapter 2) (8) | 2021.07.31 |
- Total
- Today
- Yesterday
- Visual Studio
- C# 강의
- 모바일
- 가볼만한곳
- 칵테일
- 도리도리
- 위스키
- 아이랑
- 증류주
- C# 강좌
- 서울
- 보드카
- C# 기초 강의
- 프로그램 강의
- 소주
- 가볼만한 곳
- 맥주
- 막걸리
- 와인
- 술
- C#
- 도리도리 C#
- 나들이
- WinForm
- 게임
- 광저우
- 맛집
- 전통주
- 하이볼
- 주말
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |