:より転載https://www.cnblogs.com/lackey/p/6296414.html
セクションII:スレッド・インタフェース(UI)での動作時間と空間
1.なぜのTThread?
TThreadベースのオペレーティングシステムのスレッド関数のパッケージ、退屈な細部の多くを隠します。
マルチスレッドのタスクを実現するために最も適しています。この理由は十分のために、右?
何?あなたは、マルチスレッド達成するためにWindows APIのスレッドを使うのか?
あなたはマルチスレッドタスクを達成するためのAPIを使用する場合、私は責任を、あなたを伝えることができ、
あなたは非常に迅速に把握するデルファイオブジェクト指向の考え方を才能相まって、
だから、最終的に、あなたは、開発効率を向上させるためのTThreadと同じようなことを書きます。
なぜそれを投げますか?デルファイエンジニアを信じるように、人々はすでに、すべてを通して見てきました。エヘン。
同様に、マイクロソフトのエンジニア、Windowsオペレーティングシステムがどのような大きな問題ではないと信じています。
もっと同様に、携帯電話の設計エンジニア、ノーフィルムは、彼らが最終的に携帯電話の薄型化の前に置くことを信じています。
ハハ、引き離します。。。
(このチュートリアルでは、デフォルトのオペレーティングシステムは、Windows 7月10日、デルファイバージョンはXE8で、コードのほとんどはXE2上で実行することができますです)
何戸口最後に2スレッド時空のユーザーインターフェイス(UI)?
多くのチュートリアルを繰り返し、そのスレッドと空間を強調している、UIを更新するために直接行くことを許されていませんが、理由を説明していないようです。
私たちは、UIインターフェイスは、更新に同時に複数のスレッドを可能にすることを想定し、何が起こるかを参照してください。
2つのスレッドが同時にそのような赤、緑いずれかを描画するように、インターフェース描画操作の同じ地域に進む場合、
だから、最終的には、それは大きな塗装の顔が画面に表示されない可能性がありますか?
シンプルで理解するように、これは、UIは、マルチスレッドが動作することはできませんなぜあなたが知っている、ことができます。ことができないではない、それは最後の手段です。
(スレッドがUIを直接操作することはできませんが、同じことがアンドリュースに適用されます)
3. TThread.Synchronize()原理。
SendMessage関数は、ウィンドウWM_NULLにメッセージを送る、です。
ニュースの窓を受け取った後のインタフェースを更新します。イベントに応答して、ウィンドウメッセージはメインスレッドとスペースを理解することができます。
以下は、正しく表示する方法についての計算結果ウィンドウ接続部の一例です。
unit
Unit10;
interface
uses
Winapi
.
Windows, Winapi
.
Messages, System
.
SysUtils, System
.
Variants, System
.
Classes,
Graphics,
Vcl
.
Controls, Vcl
.
Forms, Vcl
.
Dialogs, uAccumulation, Vcl
.
StdCtrls;
type
TForm10 =
class
(TForm)
Edit1: TEdit;
Button1: TButton;
procedure
Button1Click(Sender: TObject);
private
procedure
OnAccumulated(Sender: TAccumulationThread);
end
;
implementation
{
$R
*.dfm}
procedure
TForm10
.
Button1Click(Sender: TObject);
var
accThread: TAccumulationThread;
begin
accThread := TAccumulationThread
.
Create(
true
);
accThread
.
OnAccumulated := self
.
OnAccumulated;
//指定事件。
accThread
.
FreeOnTerminate :=
true
;
// 线程结束后自动释放
accThread
.
Num :=
100
;
accThread
.
Start;
end
;
procedure
TForm10
.
OnAccumulated(Sender: TAccumulationThread);
begin
// 这里是线程时空
// 要更新 UI ,要用 Synchorinize 把更新的操作
// 塞到主线程时空里去运行。注意理解:“塞!”
TThread
.
Synchronize(
nil
,
procedure
begin
// 这里的代码被塞到主线程时空里去了。
Edit1
.
Text := inttostr(Sender
.
Total);
end
);
// Synchronize 第一个参数是 nil
// 第二个参数是一个匿名函数 什么是匿名函数? 以后会介绍到。
end
;
end
.
|
unit uAccumulation; interface uses Classes; type TAccumulationThread = class; //此为提前申明 TOnAccumulated = procedure(Sender: TAccumulationThread) of object; // 如果不提前申明,Sender 就要定义成 TObject // 在事件函数中,要操作 Sender 就需要强制转换 TAccumulationThread = class(TThread) protected procedure Execute; override; public Num: integer; Total: integer; OnAccumulated: TOnAccumulated; end; implementation procedure TAccumulationThread.Execute; var i: integer; begin Total := 0; if Num > 0 then begin for i := 1 to Num do Total := Total + i end; // 当计算完成后,就调用 OnAccumulated 通知调用者 if Assigned(OnAccumulated) then OnAccumulated(self); end; end.
4. 哪些代码运行在线程时空?
Execute 函数中运行的、调用的代码,都是”线程代码“。与代码书写位置无关!!!
Sysnchronize 是个特殊的存在,它可以在线程时空里,把代码塞到主线程时空里去运行。
第三节,将实现线程如何保持生命力,创建后可以反复使用。慢慢进入实用阶段了,请不要错过。