RAD Studio 10.3.3 测试√
- 关于线程也可以看看这篇:Delphi 线程的开始、暂停、继续、停止
小知识:
- 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;
我也是前几天碰到了这个情况,在这里做一下笔记,巩固一下
一点点笔记,以便以后翻阅。