Delphi でスレッド セーフなコードを記述するには、他の言語で行うような基本的な注意が必要です。これは、競合状態に対処することを意味します。異なるスレッドが同じデータにアクセスすると、競合状態が発生します。これに対処する良い方法は、TCriticalSectionのインスタンスを宣言し、その中に危険なコードをラップすることです。
以下のコードは、仮説により、競合状態を持つプロパティのゲッターとセッターを示しています。
constructor TMyThread.Create;
begin
CriticalX := TCriticalSection.Create;
end;
destructor TMyThread.Destroy; override;
begin
FreeAndNil(CriticalX);
end;
function TMyThread.GetX: string;
begin
CriticalX.Enter;
try
Result := FX;
finally
CriticalX.Leave;
end;
end;
procedure TMyThread.SetX(const value: string);
begin
CriticalX.Enter;
try
FX := Value;
finally
CriticalX.Leave;
end;
end;
TCriticalSection ( CriticalX )の 1 つのインスタンスを使用して、データ メンバーFXへのアクセスをシリアル化していることに注意してください。
ただし、Delphi には追加の考慮事項があります。VCL はスレッド セーフではないため、VCL の競合状態を回避するには、画面の変更が発生するすべての操作をメイン スレッドで実行する必要があります。Synchronizeメソッド内でそのようなコードを呼び出すことで、これを取得できます。上記のクラスを考慮すると、次のようにする必要があります。
procedure TMyThread.ShowX;
begin
Synchronize(SyncShowX);
end;
procedure TMyThread.SyncShowX;
begin
ShowMessage(IntToStr(FX));
end;
Delphi 2010以降を使用している場合は、匿名メソッドを利用する簡単な方法があります。
procedure TMyThread.ShowX;
begin
Synchronize(procedure begin
ShowMessage(IntToStr(FX));
end);
end;
これが役立つことを願っています!