Delphi 线程TThread中的Synchronize()方法

RAD Studio 10.3.3 测试√




小知识:

  • RTL(Run-Time library),运行时库,包括System、SysUtils、Math三个单元,提供的函数与语言、编译器、操作系统及进程有关,RTL提供类之间继承于 TObject 和 RTL内部的类
  • VCL(Visual Component Library),可视化组件库,包括Graphics、classes、Controls等与类和组件相关的单元
  • VCL不是线程安全的
    因为VCL不是线程安全的,所以对VCL的访问只能在主线程中。这将意味着:所有需要与用户打交道的代码都只能在主线程的环境中执行。
    开发多线程项目的主要需要考虑的一点就是同步多线程使用资源,不要产生冲突,但是VCL不是线程安全的,不能让其他的线程使用,只能通过主线程来使用它
  • 在 TThread中有一个方法叫Synchronize(),通过它可以让子线程的一些方法在主线程中执行
    Synchronize() 的作用是在主线程中执行一个方法
  • 使用Synchronize() 方法来调用子线程想要将数据“写到”界面的方法,这样就能保证这个方法实际上是在主线程中执行的(虽然它是子线程的方法,但是通过Synchronize() 方法可以实现将子线程的方法放到主线程中执行),这样就能保证不会出现多个线程使用VCL 组件
  • 当你在程序中第一次创建一个附属线程时,VCL 将会从主线程环境中创建和维护一个隐含的线程窗口。此窗口唯一的目的是把通过Synchronize() 调用的方法排队

窗体情况:

  • Form1【使用的线程相关的附加内容下面的两个Button按钮,show窗体2】
    在这里插入图片描述
  • Form2
    在这里插入图片描述

代码:

  • 在子线程中执行的情况:
begin
  // 为了方便使用的匿名线程
  TThread.CreateAnonymousThread(
    procedure
    begin
      // 这是直接在子线程中执行的,会产生意外的
      Form2.Show;
    end).Start;
end;

这样直接在子线程中调用窗体的show方法,会出现窗体上面有的东西不显示,主要是面板类的,关闭程序的时候会出现【无效的窗口句柄】,如下图
在这里插入图片描述

在这里插入图片描述

  • 使用Synchronize()方法的情况
begin
  // TThread 中的 Synchronize()
  TThread.CreateAnonymousThread(
    procedure
    begin
      TThread.Synchronize(nil,
        procedure
        begin
          Form2.Show;
        end)
    end).Start;
end;

使用 Synchronize() 方法,让其在主线中执行,就不会出现上面的情况,你会发现一切正常


非阻断延迟

// 非阻断延迟 MSecs:延迟的时间(ms)
procedure delay(MSecs: LongInt);
var
  FirstTickCount, Now: LongInt;
begin
  FirstTickCount := GetTickCount();
  repeat
    Application.ProcessMessages;
    Now := GetTickCount();
  until (Now - FirstTickCount >= MSecs) or (Now < FirstTickCount);
end;

我也是前几天碰到了这个情况,在这里做一下笔记,巩固一下

一点点笔记,以便以后翻阅。

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Delphi 线程是一种轻量级的执行单元,它可以在程序独立运行,不会影响主线程的执行。使用线程可以提高程序的并发性和响应性,使得程序可以同时处理多个任务。 在 Delphi 创建线程可以使用 TThread 类,这个类封装了线程的创建、启动、停止等操作。以下是一个简单的示例: ```delphi type TMyThread = class(TThread) protected procedure Execute; override; end; implementation procedure TMyThread.Execute; begin // 线程执行的代码 end; var MyThread: TMyThread; begin MyThread := TMyThread.Create(True); MyThread.FreeOnTerminate := True; MyThread.Resume; // 启动线程 end. ``` 在上面的代码,我们创建了一个继承自 TThread 的自定义线程类 TMyThread,并实现了 Execute 方法,这个方法线程执行的入口点。然后在主程序创建一个 TMyThread 对象 MyThread,并设置 FreeOnTerminate 属性为 True,表示线程执行结束后自动释放线程对象。最后调用 Resume 方法启动线程。 在线程的 Execute 方法,我们可以编写线程的具体操作代码,例如访问网络、执行耗时任务等。需要注意的是,在线程不能直接访问主线程的界面控件,必须使用 Synchronize 方法或者使用 PostMessage 等方法将操作传递给主线程执行。 在 Delphi 还提供了一些辅助类和方法来简化线程的使用,例如 TThreadList、TInterlocked 等。使用这些类和方法可以更方便、更安全地实现线程间的数据共享和同步。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小印丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值