Delphi实现简单多线程

Delphi
placeholder image
admin 发布于:2017-11-17 16:02:44
阅读:loading

基本介绍

对于我这种Delphi渣渣选手来说,整这么一个破玩意儿真不好搞,网上找半天示例还找不到一个纯净版的实现,找到好多示例实现起来的也各不一样,于是乎就有了这篇文章~~如果写过java的swing程序就很清楚,一个主线程为主程序,所有的*作在其基础上完成的,如果其中有一个*作需要等待延迟执行或者查询数据库耗时较长,我们的程序会出现(看似)卡死的情况,你不能再对其进行控制,直到它的当前*作已经被完成。就跟ajax的请求一样,把ajax的请求设置为同步时,浏览器一样会呈现卡住的情况,直到请求响应后才可以再操作其他,类似这种我们将ajax设置为异步即可。同样的CS端程序需要重新启动一个线程专门去干这件事情。

本示例主要有两个小点:

(1)点击普通按钮将进行10次循环,每次循环将休眠1秒,我们发现在程序执行的过程中,我们无法拖动窗口,无法将其关闭,无法选中文本域中的文本等等,必须要等到程序的10次休眠执行完毕才可以;

(2)点击多线程按钮同样进行10次循环,开启一个新的线程去执行逻辑,主线程不会受其影响,我们可以拖动窗口,关闭窗口,选择文本域中的内容等等;

代码参考

image.png

参考代码

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.

运行效果

多线程示例.gif

上图在执行【普通】按钮的*作时,我们发现当循环正在执行时,无法对文本域的内容进行选中操作,并且实际是这个小程序出现了卡死(标题栏显示的),鼠标也出现了忙碌的状态;而点击【多线程】按钮时,各种情况都显示正常了。

 点赞


 发表评论

当前回复:作者

 评论列表


留言区