Delphi中的多线程
问题入门
先看一个程序
procedure TForm1.btn1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 500000 do
begin
Canvas.TextOut(10, 10, i.ToString);
end;
end;
结果如下图,循环执行中,界面卡住,无法响应鼠标事件,直到运行完成。
有一个简单方法
Application.ProcessMessages
,加入这个方法后可以响应鼠标事件,但是响应的同时,循环会终止,也就是鼠标事件和循环是同步的,同时只能执行一个
procedure TForm1.btn1Click(Sender: TObject);
var
i: Integer;
begin
for i := 0 to 500000 do
begin
Application.ProcessMessages;
Canvas.TextOut(10, 10, i.ToString);
end;
end;
多线程解决方法
- 调用
API
procedure TForm1.btn1Click(Sender: TObject);
var
ID: Cardinal;
begin
CreateThread(nil, 0, @myfun, nil, 0, ID);
end;
function myfun: integer;
var
i: integer;
begin
for i := 0 to 400000 do
begin
Form1.Canvas.TextOut(10, 10, i.ToString);
end;
result := 0;
end;
注意,可能会有错乱,这是因为我们用CreateThread
创建的线程中操作了ui,而主线程也在操作ui,2者冲突了,如果又有别的子线程也访问了同一个ui资源,那就更乱了。myfun
函数需要改成如下代码,线程中操作界面前,先锁住,使用完ui资源后再释放所就没问题了。
function myfun: integer;
var
i: integer;
begin
for i := 0 to 400000 do
begin
Form1.Canvas.Lock; //新
Form1.Canvas.TextOut(10, 10, i.ToString);
Form1.Canvas.Unlock; //新
end;
result := 0;
end;
- 使用
TThread
类
TMyThread = class(TThread)
protected
procedure Execute; override;
end;
//..............
{ TMyThread }
procedure TMyThread.Execute;
var
i: integer;
begin
inherited;
FreeOnTerminate := True; { 这可以让线程执行完毕后随即释放 }
for i := 0 to 400000 do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut(10, 10, i.ToString);
Form1.Canvas.Unlock;
end;
end;
procedure TForm1.btn1Click(Sender: TObject);
var
ID: Cardinal;
begin
// CreateThread(nil, 0, @myfun, nil, 0, ID);
TMyThread.Create(false);
end;
效果同调用API
- 使用
CreateAnonymousThread
静态方法
procedure TForm1.btn1Click(Sender: TObject);
var
ID: Cardinal;
begin
// CreateThread(nil, 0, @myfun, nil, 0, ID);
// TMyThread.Create(false);
TThread.CreateAnonymousThread(myfun).Start; //注意myfun必须是方法,不能是函数
end;
procedure myfun;
var
i: integer;
begin
for i := 0 to 400000 do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut(10, 10, i.ToString);
Form1.Canvas.Unlock;
end;
end;
也可以直接写匿名方法
procedure TForm1.btn1Click(Sender: TObject);
var
ID: Cardinal;
begin
// CreateThread(nil, 0, @myfun, nil, 0, ID);
// TMyThread.Create(false);
TThread.CreateAnonymousThread(
procedure
var
i: integer;
begin
for i := 0 to 400000 do
begin
Form1.Canvas.Lock;
Form1.Canvas.TextOut(10, 10, i.ToString);
Form1.Canvas.Unlock;
end;
end).Start;
end;
标签:10,begin,end,Delphi,Canvas,Form1,var,多线程
From: https://www.cnblogs.com/yangwanli2010/p/16983371.html