本文為大家分享了c#多線程之線程控制,供大家參考,具體內(nèi)容如下
方案一:
調(diào)用線程控制方法.啟動(dòng):thread.start();停止:thread.abort();暫停:thread.suspend();繼續(xù):thread.resume();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
private void btn_start_click( object sender, eventargs e) { mthread.start(); // 開始 } private void btn_stop_click( object sender, eventargs e) { mthread.abort(); // 終止 } private void btn_suspend_click( object sender, eventargs e) { mthread.suspend(); // 暫停 } private void btn_resume_click( object sender, eventargs e) { mthread.resume(); // 繼續(xù) } |
線程定義為:
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
|
mthread = new thread(() => { try { for ( int j = 0; j < 20; j++) { int vsum = 0; this .textbox1.text += "--->" ; for ( int i = 0; i < 100000000; i++) { if (i % 2 == 0) { vsum += i; } else { vsum -= i; } } this .textbox1.text += string .format( "{0} => vsum = {1}\r\n" , datetime.now.tostring(), vsum); thread.sleep(1000); } } catch (threadabortexception ex) { console.writeline( "threadabortexception:{0}" , ex.message); } }); |
值得注意的是: 通過 thread.abort() 停下來的線程(或自行運(yùn)行結(jié)束的線程),都無法直接通過 thread.start() 方法再次啟動(dòng),必須重新創(chuàng)建一個(gè)線程啟動(dòng)。
所以,“開始按鈕”事件應(yīng)為:
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
|
private void btn_start_click( object sender, eventargs e) { // 定義線程 mthread = new thread(() => // lambda 表達(dá)式 { try { for ( int j = 0; j < 20; j++) { int vsum = 0; this .textbox1.text += "--->" ; for ( int i = 0; i < 100000000; i++) { if (i % 2 == 0) { vsum += i; } else { vsum -= i; } } this .textbox1.text += string .format( "{0} => vsum = {1}\r\n" , datetime.now.tostring(), vsum); thread.sleep(1000); } } catch (threadabortexception ex) { console.writeline( "threadabortexception:{0}" , ex.message); } }); mthread.start(); // 開始 } |
此外,對(duì)于 thread.suspend() 和 thread.resume() 方法,微軟已經(jīng)將其標(biāo)記為過時(shí):
thread.suspend has been deprecated. please use other classes in system.threading, such as monitor, mutex, event, and semaphore, to synchronize threads or protect resources. (thread.suspend 已被否決。請(qǐng)使用系統(tǒng)中的其他類線程,如監(jiān)視器、互斥體、事件和信號(hào)量,以同步線程或保護(hù)資源。)
因?yàn)椋瑹o法判斷當(dāng)前掛起線程時(shí)它正在執(zhí)行什么代碼。如果在安全權(quán)限評(píng)估期間掛起持有鎖的線程,則 appdoamin 中的其它線程可能被阻止。如果在線程正執(zhí)行構(gòu)造函數(shù)時(shí)掛起它,則 appdomain 中嘗試使用該類的其它線程將被阻止。這樣容易發(fā)生死鎖。
方案二:
在 線程運(yùn)行過程中 適當(dāng)?shù)奈恢茫ㄈ缒硞€(gè)完整的功能/命令后)判斷是否要繼續(xù)線程,再?zèng)Q定線程的命運(yùn)。
1.定義一個(gè)全局變量:
1
|
int mtdflag = 0; // 1:正常運(yùn)行;2:暫停;3:停止 |
2. 定義一個(gè)判斷方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
bool waitforcontinue() { if ( this .mtdflag == 3) { return false ; // 返回false,線程停止 } else if ( this .mtdflag == 2) { while (mtdflag != 1) { thread.sleep(200); // 假暫停;停頓時(shí)間越短,越靈敏 if ( this .mtdflag == 3) { return false ; // 返回false,線程停止 } } } return true ; // 返回true,線程繼續(xù) } |
3.修改 控制命令 事件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
private void btn_stop_click( object sender, eventargs e) { this .mtdflag = 3; //mthread.abort(); // 終止 } private void btn_suspend_click( object sender, eventargs e) { this .mtdflag = 2; //mthread.suspend(); // 暫停 } private void btn_resume_click( object sender, eventargs e) { this .mtdflag = 1; //mthread.resume(); // 繼續(xù) } |
4.在線程運(yùn)行過程中適當(dāng)?shù)奈恢茫袛嗑€程是否繼續(xù)
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
|
mthread = new thread(() => { try { for ( int j = 0; j < 20; j++) { int vsum = 0; this .textbox1.text += "--->" ; for ( int i = 0; i < 100000000; i++) { if (i % 2 == 0) { vsum += i; } else { vsum -= i; } if (i % 10000000 == 0) { this .textbox1.text += "." ; } if (!waitforcontinue()) // 返回 false 則,停止 { break ; //return; } } this .textbox1.text += string .format( "{0} => vsum = {1}\r\n" , datetime.now.tostring(), vsum); if (!waitforcontinue()) // 返回 false 則,停止 { break ; // return; } thread.sleep(1000); } } catch (threadabortexception ex) { console.writeline( "threadabortexception:{0}" , ex.message); this .textbox1.text += ex.message + "..." ; } finally { this .textbox1.text += "線程已結(jié)束" ; } }); |
在窗體中,解決跨線程訪問問題:在窗體構(gòu)造函數(shù)中添加代碼: control.checkforillegalcrossthreadcalls = false;
原文鏈接:http://www.cnblogs.com/CUIT-DX037/p/6955873.html