亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

c# 多線程編程 入門篇

2020-01-31 20:52:23
字體:
來源:轉載
供稿:網友
開始本應該是一篇洋洋灑灑的文字, 不過我還是提倡先做起來, 在嘗試中去理解.


先試試這個:



 
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 500000 do
begin
Canvas.TextOut(10, 10, IntToStr(i));
end;
end;
 
 


上面程序運行時, 我們的窗體基本是 "死" 的, 可以在你在程序運行期間拖動窗體試試...

Delphi 為我們提供了一個簡單的辦法(Application.ProcessMessages)來解決這個問題:



 
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 500000 do
begin
Canvas.TextOut(10, 10, IntToStr(i));
Application.ProcessMessages;
end;
end;
 
 


這個 Application.ProcessMessages; 一般用在比較費時的循環中, 它會檢查并先處理消息隊列中的其他消息.

但這算不上多線程, 譬如: 運行中你拖動窗體, 循環會暫停下來...

在使用多線程以前, 讓我們先簡單修改一下程序:



 
function MyFun: Integer;
var
i: Integer;
begin
for i := 0 to 500000 do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut(10, 10, IntToStr(i));
Form1.Canvas.Unlock;
end;
Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
MyFun;
end;
 
 


細數上面程序的變化:
1、首先這還不是多線程的, 也會讓窗體假 "死" 一會;
2、把執行代碼寫在了一個函數里, 但這個函數不屬于 TForm1 的方法, 所以使用 Canvas 是必須冠以名稱(Form1);
3、既然是個函數, (不管是否必要)都應該有返回值;
4、使用了 500001 次 Lock 和 Unlock.

Canvas.Lock 好比在說: Canvas(繪圖表面)正忙著呢, 其他想用 Canvas 的等會;
Canvas.Unlock : 用完了, 解鎖!

在 Canvas 中使用 Lock 和 Unlock 是個好習慣, 在不使用多線程的情況下這無所謂, 但保不準哪天程序會擴展為多線程的; 我們現在學習多線程, 當然應該用.

在 Delphi 中使用多線程有兩種方法: 調用 API、使用 TThread 類; 使用 API 的代碼更簡單.



 
function MyFun(p: Pointer): Integer; stdcall;
var
i: Integer;
begin
for i := 0 to 500000 do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut(10, 10, IntToStr(i));
Form1.Canvas.Unlock;
end;
Result := 0;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
ID: THandle;
begin
CreateThread(nil, 0, @MyFun, nil, 0, ID);
end;
 
 


代碼分析:
CreateThread 一個線程后, 算上原來的主線程, 這樣程序就有兩個線程、是標準的多線程了;
CreateThread 第三個參數是函數指針, 新線程建立后將立即執行該函數, 函數執行完畢, 系統將銷毀此線程從而結束多線程的故事.

CreateThread 要使用的函數是系統級別的, 不能是某個類(譬如: TForm1)的方法, 并且有嚴格的格式(參數、返回值)要求, 不管你暫時是不是需要都必須按格式來;
因為是系統級調用, 還要綴上 stdcall, stdcall 是協調參數順序的, 雖然這里只有一個參數沒有順序可言, 但這是使用系統函數的慣例.

CreateThread 還需要一個 var 參數來接受新建線程的 ID, 盡管暫時沒用, 但這也是格式; 其他參數以后再說吧.

這樣一個最簡單的多線程程序就出來了, 咱們再用 TThread 類實現一次



 
type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;

procedure TMyThread.Execute;
var
i: Integer;
begin
FreeOnTerminate := True; {這可以讓線程執行完畢后隨即釋放}
for i := 0 to 500000 do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut(10, 10, IntToStr(i));
Form1.Canvas.Unlock;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
TMyThread.Create(False);
end;
 
 


TThread 類有一個抽象方法(Execute), 因而是個抽象類, 抽象類只能繼承使用, 上面是繼承為 TMyThread.

繼承 TThread 主要就是實現抽象方法 Execute(把我們的代碼寫在里面), 等我們的 TMyThread 實例化后, 首先就會執行 Execute 方法中的代碼.

按常規我們一般這樣去實例化:


 
procedure TForm1.Button1Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread := TMyThread.Create(False);
end;

因為 MyThread 變量在這里毫無用處(并且編譯器還有提示), 所以不如直接寫做 TMyThread.Create(False);

我們還可以輕松解決一個問題, 如果: TMyThread.Create(True) ?
這樣線程建立后就不會立即調用 Execute, 可以在需要的時候再用 Resume 方法執行線程, 譬如:



 
procedure TForm1.Button1Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread := TMyThread.Create(True);
MyThread.Resume;
end;

//可簡化為:
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyThread.Create(True) do Resume;
end;


使用 TThread 類時, Delphi 有提供的模板, 但用 IDE 寫代碼很方便, 我重寫一遍錄下來給大家看:



期間使用了 Ctrl+J、Shift+Ctrl+C、Ctrl+Alt+P 等快捷鍵.



重要的修正與補充:


在 TThread 類的例子中, 應該有這句: FreeOnTerminate := True; (原來漏掉, 代碼中已加上; 但動畫加不上了).

先說它什么意思:
類 Create 了就要 Free;
但 TThread(的子類) 有特殊性, 很多時候我們不能確定新建的線程什么時候執行完(也就是什么時候該釋放);
如果線程執行完畢自己知道釋放就好了, 所以 TThread 給了一個布爾屬性 FreeOnTerminate, 如果為 True, 線程執行完畢后就會自釋放.

我怎么會忽略了這么重要的問題呢? 原因有二:
1、我一直在追求最精煉的代碼;
2、我手頭上不只一本書上介紹說: FreeOnTerminate 的默認值是 True(錯誤!), 經落實, 應該是 False, 起碼在 Delphi 2007 和 2009 中是這樣; 或許以前的某個版本和現在不一樣.

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品久久久久久久久久新婚| 大量国产精品视频| 国产日韩欧美一二三区| 欧美激情综合色| 日韩精品在线视频美女| 成人疯狂猛交xxx| 亚洲福利视频免费观看| 久久久精品网站| 97香蕉超级碰碰久久免费软件| 日韩电影第一页| 亚洲一区亚洲二区亚洲三区| 97精品视频在线观看| 久久视频在线观看免费| 91九色视频导航| 免费不卡在线观看av| 在线日韩第一页| 亚洲老头同性xxxxx| 国产亚洲欧洲高清一区| 欧美日韩亚洲成人| 91精品成人久久| 国产一区二区三区欧美| 日产精品99久久久久久| 中文字幕在线看视频国产欧美| 在线日韩精品视频| 亚洲成人黄色网址| 午夜美女久久久久爽久久| 亚洲最大的免费| 国产精品免费久久久| 欧美色视频日本高清在线观看| 久久久久久久久久婷婷| 国产精品美女午夜av| 欧美xxxx18国产| 精品视频一区在线视频| 日韩电影免费在线观看中文字幕| 亚洲人成网站色ww在线| 97在线观看免费高清| 日韩麻豆第一页| 国产成人精品日本亚洲| 欧美性猛交xxxx乱大交极品| 久久精品美女视频网站| 国产精品一区二区三区久久| 北条麻妃一区二区三区中文字幕| 亚洲精品成人久久| 欧美精品在线免费观看| 欧美大尺度在线观看| 国产精品老女人视频| 91中文字幕一区| 亚洲精品资源在线| 97超级碰在线看视频免费在线看| 久久精品电影网| 欧美一级电影免费在线观看| 欧美巨乳在线观看| 亚洲一区二区中文| 日韩欧美亚洲一二三区| 91精品免费久久久久久久久| 亚洲国产精品久久久久秋霞蜜臀| 国产午夜精品麻豆| 91久久国产婷婷一区二区| 欧美电影免费观看网站| 欧美性少妇18aaaa视频| 日本一本a高清免费不卡| 日本精品久久中文字幕佐佐木| 91伊人影院在线播放| 亚洲欧美另类人妖| 中文综合在线观看| 成人欧美在线观看| 韩国视频理论视频久久| 国产热re99久久6国产精品| 精品视频在线导航| 欧美亚洲国产日韩2020| 亚洲美女喷白浆| 毛片精品免费在线观看| 日韩视频―中文字幕| 久久人人爽人人| 久久久久久久999精品视频| 亚洲美女免费精品视频在线观看| 美女扒开尿口让男人操亚洲视频网站| 777午夜精品福利在线观看| 欧美剧在线观看| 成人字幕网zmw| 亚洲精品www久久久久久广东| 91精品久久久久久综合乱菊| 亚洲人成在线观看网站高清| 久久影视电视剧凤归四时歌| 成人免费自拍视频| 欧美激情视频一区| 国产日韩欧美夫妻视频在线观看| 亚洲一区制服诱惑| 亚洲国产女人aaa毛片在线| 91黑丝高跟在线| 日韩欧美高清视频| 国产成人av在线| 成人观看高清在线观看免费| 久久五月天综合| 国产亚洲视频在线观看| 欧美日韩999| 黑人精品xxx一区| 九九视频这里只有精品| 国产大片精品免费永久看nba| 欧洲永久精品大片ww免费漫画| 伊是香蕉大人久久| 久久夜色精品亚洲噜噜国产mv| 久久久久久久激情视频| 777精品视频| 国产午夜精品麻豆| 自拍视频国产精品| 91精品国产777在线观看| 亚洲第一区在线| 日韩欧美在线播放| 精品女厕一区二区三区| 亚洲乱码国产乱码精品精| 亚洲成色999久久网站| 97视频免费看| 91精品国产综合久久香蕉的用户体验| 国产精品久久久久aaaa九色| www.日韩系列| 久久免费少妇高潮久久精品99| 日韩中文理论片| 91精品久久久久久久久中文字幕| 久久夜色精品亚洲噜噜国产mv| 91精品中国老女人| 国产精品免费看久久久香蕉| 久久久www成人免费精品张筱雨| 久久久久久久久久久人体| 成人午夜激情网| www.欧美三级电影.com| 岛国av一区二区| 日本成人免费在线| 日韩a**站在线观看| 亚洲成人a级网| 国产69精品久久久久9| 国内精品中文字幕| 国产婷婷色综合av蜜臀av| 日韩中文字幕欧美| 日韩电影中文 亚洲精品乱码| 欧美日韩在线免费| 97香蕉超级碰碰久久免费软件| 欧美日韩国产黄| 国内揄拍国内精品少妇国语| 国产经典一区二区| 一区二区欧美久久| 国产91精品黑色丝袜高跟鞋| 亚洲新中文字幕| 狠狠做深爱婷婷久久综合一区| 狠狠躁天天躁日日躁欧美| 精品久久香蕉国产线看观看gif| 日韩最新在线视频| 亚洲精品日韩久久久| 国产成人综合精品| 搡老女人一区二区三区视频tv| 久久艳片www.17c.com| 97视频在线看| 欧美大学生性色视频| 亚洲精品国产品国语在线| 久久精品中文字幕一区| 日韩最新在线视频| 中文字幕不卡在线视频极品| 中日韩午夜理伦电影免费| 亚洲第一视频网| 国产精品美女视频网站| 国产精品白丝jk喷水视频一区| 久久久黄色av| 国产91成人在在线播放| 91精品国产91久久久久久不卡|