利用多线程解除耦合/线程解耦合/DeAfterCreate/DeClose

当软件启动时,我们希望从配置文件中加载参数,然后用这些参数,改变窗口的状态大小,或者组件的属性。

通常的做法是在 TForm 的 OnCreate 事件中或者 OnFirstShow 事件中执行这些任务。 但是,但某些改变窗口的语句,

在这些事件中执行时,是会发生冲突的。比如:在 OnShow 事件中,不能去改变 visiable 属性。因此,我们需要一个真正解除耦合的事件,

此处将其定义为 DeAfterCreate , 即称为 解除耦合的 AfteCreate 事件。 同样地,也实现了一个 DeClose 事件。

本例源代码(delphi 10.3.2)

 1 unit uFrmDeBase;
 2 
 3 interface
 4 
 5 uses
 6   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 7   Vcl.Controls, Vcl.Forms, Vcl.Dialogs;
 8 
 9 type
10   TFrmDeBase = class(TForm)
11     procedure FormShow(Sender: TObject);
12   private
13     { Private declarations }
14     FNotFirstShow: Boolean; // 取名为这样是利用默认值为 false, 减少去 create 事件中去赋值。
15   protected
16     procedure DeAfterCreate(); virtual;
17     procedure DeClose();
18   public
19     { Public declarations }
20   end;
21 
22 implementation
23 
24 {$R *.dfm}
25 
26 procedure TFrmDeBase.DeAfterCreate;
27 begin
28 end;
29 
30 procedure TFrmDeBase.DeClose;
31 begin
32   TThread.CreateAnonymousThread(
33     procedure
34     begin
35       TThread.Queue(nil,
36         procedure
37         begin
38           Self.Close;
39         end);
40     end).Start; // 创建一个匿名线程
41     // 在匿名线程中,再排队执行主线程时空的代码
42 end;
43 
44 procedure TFrmDeBase.FormShow(Sender: TObject);
45 begin
46   // 我们利用 FirstOnShow 这个时机,创造一个解除耦合的 DeAfterCreate 事件。
47   if not FNotFirstShow then
48   begin
49     FNotFirstShow := true;
50     TThread.CreateAnonymousThread(
51       procedure
52       begin
53         TThread.Queue(nil,
54           procedure
55           begin
56             DeAfterCreate;
57           end);
58 
59       end).Start;
60   end;
61 end;
62 
63 end.
 1 unit uFrmMain;
 2 
 3 interface
 4 
 5 uses
 6   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
 7   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, uFrmDeBase, Vcl.StdCtrls;
 8 
 9 type
10   TFrmMain = class(TFrmDeBase)
11     Button1: TButton;
12     procedure Button1Click(Sender: TObject);
13   private
14     { Private declarations }
15   protected
16     procedure DeAfterCreate(); override;
17   public
18     { Public declarations }
19   end;
20 
21 var
22   FrmMain: TFrmMain;
23 
24 implementation
25 
26 {$R *.dfm}
27 { TFrmMain }
28 
29 procedure TFrmMain.Button1Click(Sender: TObject);
30 begin
31   inherited;
32   DeClose;
33   // 你可以在各种事件中(OnClose事件中除外),执行 DeClose 函数。
34   // 不必担心耦合问题。
35   // 这个相当于“延时执行” Close 动作。
36   // ***
37   // 如果没有解除耦合,就可能在 Close 动作之后,返回到别的事件函数中,执行了比如设置组件信息操作。导致出错。
38   // “延时执行”,相当于此函数不在“任何函数中调用的。“完全独立”。
39   // 解除耦合,是很重要的编程思维,可以让多任务,复杂关系调用简单化。
40 end;
41 
42 procedure TFrmMain.DeAfterCreate;
43 begin
44   // 此处是解耦合的 AfterCreate 事件
45   // 在此时,窗口已经真正创建完毕
46   // 可以在此处加载各种参数
47   // 可以设置窗口大小,位置,等信息而不会发生错误。
48   /// *****************
49   // 比如:你直接在 OnShow / OnCreate 等其它事件中
50   // 因为没有解除耦合,下面的功能会发生错误
51   self.Position := poScreenCenter;
52   self.Visible := false;
53   self.Visible := true;
54   self.BringToFront;
55 end;
56 
57 end.
原文地址:https://www.cnblogs.com/lackey/p/15508864.html