转载自:https://www.cnblogs.com/lackey/p/6297115.html
// 普通编程function Accumulate(num:integer):integer;var i:integer;begin result:=0; if num<1 then exit; for i:=1 to num do result:=result+i;end;// 在 Button1 的 OnClick 事件中编写如下代码:var n,Total:integer;begin n:=100; Total:=Accumelate(n); // 等待计算结果,假设计算需要5分钟,此处就得等待5分钟。 // 这5分钟内,界面是无法访问的,是假死的。 // 计算完成,得到结果 Total=5050; DoSomeThing; //接着执行此句。end; |
// 多线程编程,此为计算线程类unit uAccumulation;interfaceuses Classes;type TAccumulationThread = class; TOnAccumulated = procedure(Sender: TAccumulationThread) of object; TAccumulationThread = class(TThread) protected procedure Execute; override; public Num: integer; Total: integer; OnAccumulated: TOnAccumulated; end;implementationprocedure TAccumulationThread.Execute;var i: integer;begin inherited; Total := 0; if Num > 0 then begin for i := 1 to Num do Total := Total + i end; // 当计算完成后,就调用 OnAccumulated 通知调用者 if Assigned(OnAccumulated) then OnAccumulated(self);end;end. |
// 调用多线程 // 在FrmMain 中定义 OnAccumulated 事件函数 Procedure TFrmMain.OnAccumulated(Sender:TAccumulationThread); var sum:integer; begin // 当计算完成时,计算线程就调用本事件函数。 // 我们在这里就得到了计算结果 sum:=Sender.Total; // 因为这里是线程时空,不能直接把 sum 的值显示到界面上。 // 如何正确显示,将下一章节中讲解。 end; // 在Button1 的OnClick 事件中编写下面的代码 var thd:TAccumulationThread; begin // 此处为主线程时空。 thd:=TAccumuationThread.Create(true); thd.OnAccumulated=Self.OnAccumulated; // Self 指是 FrmMain. thd.Num:=100; thd.Start; //启动线程,在线程时空中执行 Execute 中的代码。 // start 立即返回并执行下一条代码 DoSomeThing; // 此时,就有两个线程在同时执行。 // 1.主线程,也就是此处运行的时代码。 // 2.计算线程,也就是 Execute 中的代码,这些代码此时运行于多线程时空。 // 由于是两个线程并行在执行,故此处 DoSomeThing 马上可以执行。 // 界面也不会假死 DoSomeThing; end;
原文:https://www.cnblogs.com/approx/p/11852128.html