首页 > 其他分享 >Delphi中的多线程

Delphi中的多线程

时间:2022-12-14 19:55:40浏览次数:38  
标签:10 begin end Delphi Canvas Form1 var 多线程

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

相关文章

  • 咸鱼学Java-多线程基础
    实现多线程的方法1.继承Thread,并且重写run方法(线程体)2.实现Runnable接口,实现run方法(线程体)必须重写run1.继承ThreadclassMyThreadextendsThread{publicMyThr......
  • spring boot创建多线程定时任务
    @Component@EnableScheduling//1.开启定时任务@EnableAsync//2.开启多线程publicclassMultithreadScheduleTask{@Async@Schedule......
  • Delphi 指针[3]指针运算符(Pointer operators)
    Delphi指针[3]指针运算符(Pointeroperators) 关系运算符<、>、<=和>=可以接受PChar和PWideChar类型的操作数。以下运算符也将指针作为操作数。字符指针运算符运算符......
  • Delphi 指针[2] 指针类型(Pointer types)
    Delphi指针[2]指针类型(Pointertypes)可以使用以下语法声明指向任何类型的指针typepointerTypeName=^type定义记录或其他数据类型时,通常也会定义指向该类型的指......
  • Delphi(lazarus) TStringHelper用法详解(转载)
    Delphi(lazarus)TStringHelper用法详解DelphiXE4的TStringHelper,对操作字符串进一步带来更多的方法,使用这些方法才可以实现跨平台的代码。Delphi引用单元:System.Sys......
  • for 循环返回List,多线程速度慢的解决方案
    /**过于耗时必须休眠否则线程长期占用会发生gc不能及时回收资源,cpu占用率也会可能飙高***/CompletableFuture<Map<String,String>>month=Completabl......
  • C# 使用多线程在关闭窗体时如何关闭所有线程,使程序退出不产生报错
    在winform开发中,程序内部使用了多线程或定时器等功能,在关闭窗体退出程序时,如果只有UI线程关闭,而托管线程还在运行就会报错。关闭线程的方法有以下几种,其中最彻底的方法为:S......
  • <一>通过thread类编写C++多线程程序
    C++语言层面多线程=>好处:跨平台windows/linuxthread/mutex/condition_variablelock_gurad/unique_lockatomic/原子类型,基于CAS操作的原子类型线程安全的睡眠sleep_f......
  • Delphi 11.2应用体验报告
    Delphi11.2按个人预期发布了!官方下载地址:​​https://altd.embarcadero.com/download/radstudio/11.0/RADStudio_11_2_10937a.iso​​,安装过程:如果你从11.1安装,则是无缝升......
  • delphi编写sql脚本文件批量执行程序
    程序使用DelphiXE11.1开发,用到控件UniDac9.1.1,QDAC里面的Qlog组件。程序实现了SQL脚本文件批处理执行应用,运行效果图。  文件.pas代码unitmain;interfaceuses......