Delphi实现简单多线程
Delphiadmin 发布于:2017-11-17 16:02:44
阅读:loading
对于我这种Delphi渣渣选手来说,整这么一个破玩意儿真不好搞,网上找半天示例还找不到一个纯净版的实现,找到好多示例实现起来的也各不一样,于是乎就有了这篇文章~~如果写过java的swing程序就很清楚,一个主线程为主程序,所有的*作在其基础上完成的,如果其中有一个*作需要等待延迟执行或者查询数据库耗时较长,我们的程序会出现(看似)卡死的情况,你不能再对其进行控制,直到它的当前*作已经被完成。就跟ajax的请求一样,把ajax的请求设置为同步时,浏览器一样会呈现卡住的情况,直到请求响应后才可以再操作其他,类似这种我们将ajax设置为异步即可。同样的CS端程序需要重新启动一个线程专门去干这件事情。
本示例主要有两个小点:
(1)点击普通按钮将进行10次循环,每次循环将休眠1秒,我们发现在程序执行的过程中,我们无法拖动窗口,无法将其关闭,无法选中文本域中的文本等等,必须要等到程序的10次休眠执行完毕才可以;
(2)点击多线程按钮同样进行10次循环,开启一个新的线程去执行逻辑,主线程不会受其影响,我们可以拖动窗口,关闭窗口,选择文本域中的内容等等;
参考代码
unit ThreadTest;
{
多线程的定义和调用
单线程处理任务的弊端
}
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TthreadWindow = class(TForm)
badButton: TButton;
threadButton: TButton;
content: TMemo;
procedure badButtonClick(Sender: TObject);
procedure threadButtonClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
CountThreadClass = class(TThread) //声明一个线程类,使用它的实例对象
private
{ Private declarations }
content: TMemo;
public
{ Public declarations }
//声明类的相关函数
procedure Execute;override;//执行
end;
var
threadWindow: TthreadWindow;
implementation
{$R *.dfm}
//普通单线程的事物
procedure TthreadWindow.badButtonClick(Sender: TObject);
var
vIndex : integer;
begin
//--------清空行数据
vIndex := content.Lines.Count;
while vIndex >= 0 do begin
content.Lines.Delete(vIndex);
vIndex := vIndex - 1;
end;
//--------每0.5秒追加一行数据
for vIndex := 1 to 10 do begin
Sleep(500);
content.Lines.Add('当前写入行【' + inttostr(vIndex) + '】')
end;
end;
var countThread: CountThreadClass;//声明一个线程类的实例
procedure CountThreadClass.Execute;
var
vIndex : integer;
begin
FreeOnTerminate := true;//线程执行完后自动销毁
//--------清空行数据
vIndex := content.Lines.Count;
while vIndex >= 0 do begin
content.Lines.Delete(vIndex);
vIndex := vIndex - 1;
end;
//--------每0.5秒追加一行数据
for vIndex := 1 to 10 do begin
Sleep(500);
content.Lines.Add('当前写入行【' + inttostr(vIndex) + '】')
end;
end;
procedure TthreadWindow.threadButtonClick(Sender: TObject);
begin
countThread := CountThreadClass.Create(true);//false为立即执行
countThread.content := content;//线程对象赋值
countThread.Resume;//手动执行需要使用MyThread.Resume;
end;
end.
上图在执行【普通】按钮的*作时,我们发现当循环正在执行时,无法对文本域的内容进行选中操作,并且实际是这个小程序出现了卡死(标题栏显示的),鼠标也出现了忙碌的状态;而点击【多线程】按钮时,各种情况都显示正常了。
点赞