利用多線程解除耦合/線程解耦合/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.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM