zoukankan      html  css  js  c++  java
  • 利用多线程解除耦合/线程解耦合/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.
  • 相关阅读:
    几种常用类的学习
    类,接口
    方法
    数组使用
    条件控制与循环
    类型转换,运算符
    Java基本类型
    SVN基本使用
    【转】MySQL的btree索引和hash索引的区别
    常用命令(java、linux)
  • 原文地址:https://www.cnblogs.com/lackey/p/15508864.html
Copyright © 2011-2022 走看看