面白い

DelphiアプリケーションでのスレッドとGUIの同期

DelphiアプリケーションでのスレッドとGUIの同期


We are searching data for your request:

Forums and discussions:
Manuals and reference books:
Data from registers:
Wait the end of the search in all databases.
Upon completion, a link will appear to access the found materials.

Delphiのマルチスレッドにより、複数の同時実行パスを含むアプリケーションを作成できます。

通常のDelphiアプリケーションはシングルスレッドです。つまり、すべてのVCLオブジェクトはプロパティにアクセスし、このシングルスレッド内でメソッドを実行します。アプリケーションのデータ処理を高速化するには、1つ以上のセカンダリスレッドを含めます。

プロセッサスレッド

A アプリケーションからプロセッサへの通信チャネルです。シングルスレッドプログラムは、実行時に両方向(プロセッサとの間)に流れる通信が必要です。マルチスレッドアプリはいくつかの異なるチャネルを開くことができるため、実行速度が向上します。

スレッドとGUI

アプリケーションで複数のスレッドが実行されている場合、スレッドの実行の結果としてグラフィカルユーザーインターフェイスをどのように更新できるかという疑問が生じます。答えはTThreadクラスにあります 同期する 方法。

セカンダリスレッドからアプリケーションのユーザーインターフェイスまたはメインスレッドを更新するには、Synchronizeメソッドを呼び出す必要があります。この手法は、スレッドセーフではないオブジェクトプロパティまたはメソッドへのアクセス、または実行のメインスレッドにないリソースの使用から発生するマルチスレッドの競合を回避するスレッドセーフな方法です。

以下は、進行状況バーのあるいくつかのボタンを使用したデモの例です。各進行状況バーには、スレッド実行の現在の「状態」が表示されます。

ユニットMainU;
インタフェース
使用する
Windows、メッセージ、SysUtils、バリアント、クラス、グラフィックス、コントロール、フォーム、
ダイアログ、ComCtrls、StdCtrls、ExtCtrls;
タイプ
//インターセプタークラス
TButton = class(StdCtrls.TButton)
OwnedThread:TThread;
ProgressBar:TProgressBar;
終わり;
TMyThread = class(TThread)
プライベート
FCounter:整数;
FCountTo:整数;
FProgressBar:TProgressBar;
FOwnerButton:TButton;
手順DoProgress;
プロシージャSetCountTo(const Value:Integer);
プロシージャSetProgressBar(const値:TProgressBar);
プロシージャSetOwnerButton(const Value:TButton);
保護された
手順実行;オーバーライド;
パブリック
コンストラクターCreate(CreateSuspended:Boolean);
property CountTo:整数読み取りFCountTo書き込みSetCountTo;
プロパティProgressBar:TProgressBar読み取りFProgressBar書き込みSetProgressBar;
プロパティOwnerButton:TButton読み取りFOwnerButton書き込みSetOwnerButton;
終わり;
TMainForm = class(TForm)
Button1:TButton;
ProgressBar1:TProgressBar;
Button2:TButton;
ProgressBar2:TProgressBar;
Button3:TButton;
ProgressBar3:TProgressBar;
Button4:TButton;
ProgressBar4:TProgressBar;
Button5:TButton;
ProgressBar5:TProgressBar;
プロシージャButton1Click(Sender:TObject);
終わり;
var
MainForm:TMainForm;
実装
{$ R * .dfm}
{TMyThread}
コンストラクターTMyThread.Create(CreateSuspended:Boolean);
ベギン
継承されました;
FCounter:= 0;
FCountTo:= MAXINT;
終わり;
プロシージャTMyThread.DoProgress;
var
PctDone:拡張。
ベギン
PctDone:=(FCounter / FCountTo);
FProgressBar.Position:= Round(FProgressBar.Step * PctDone);
FOwnerButton.Caption:= FormatFloat( '0.00%'、PctDone * 100);
終わり;
プロシージャTMyThread.Execute;
const
間隔= 1000000;
ベギン
FreeOnTerminate:= True;
FProgressBar.Max:= FCountTo div Interval;
FProgressBar.Step:= FProgressBar.Max;
while FCounter <FCountTo do
ベギン
FCounter mod Interval = 0の場合Synchronize(DoProgress);
Inc(FCounter);
終わり;
FOwnerButton.Caption:= 'Start';
FOwnerButton.OwnedThread:= nil;
FProgressBar.Position:= FProgressBar.Max;
終わり;
プロシージャTMyThread.SetCountTo(const Value:Integer);
ベギン
FCountTo:=値;
終わり;
プロシージャTMyThread.SetOwnerButton(const Value:TButton);
ベギン
FOwnerButton:=値;
終わり;
プロシージャTMyThread.SetProgressBar(const Value:TProgressBar);
ベギン
FProgressBar:=値;
終わり;
プロシージャTMainForm.Button1Click(Sender:TObject);
var
aButton:TButton;
aThread:TMyThread;
aProgressBar:TProgressBar;
ベギン
aButton:= TButton(Sender);
Assigned(aButton.OwnedThread)でない場合
ベギン
aThread:= TMyThread.Create(True);
aButton.OwnedThread:= aThread;
aProgressBar:= TProgressBar(FindComponent(StringReplace(aButton.Name、 'Button'、 'ProgressBar'、)));
aThread.ProgressBar:= aProgressBar;
aThread.OwnerButton:= aButton;
aThread.Resume;
aButton.Caption:= '一時停止';
終わり
他に
ベギン
aButton.OwnedThread.Suspendedの場合
aButton.OwnedThread.Resume
他に
aButton.OwnedThread.Suspend;
aButton.Caption:= '実行';
終わり;
終わり;
終わり。

このコードサンプルを提出してくれたJens Borrisholtに感謝します。


Video, Sitemap-Video, Sitemap-Videos