2011-12-28 11 views
1

レガシーコードで作業する必要があります。このコードには、メインスレッドで作成されたTTimerがあります。 OnTimerイベントでは、タイマーはワーカースレッド内のいくつかのデータの状態を定期的にチェックしています。TTimer.OnTimerはワーカースレッドをメインスレッドと同期させますか?

擬似コード:

procedure MainForm.OnTimer(Sender: TObject); 
begin 
    if WorkerThread.Data.State = full then 
    begin 
    WorkerThread.Free; //This freezes GUI.  
    end else 
    //Do something else. 
end; 

問題はWorkerThreadが終了したとき、私はいくつかのバックグラウンド操作をしたいということです。同期を避けるために、私はDoTerminateメソッドをオーバーライドしました。しかし、この特定のケースでは、これは役に立たず、GUIはDoTerminateが終了するまでフリーズします。

私は何とかフリーズを避けることができますか?

ありがとうございました。

+0

だからあなたはDoTerminateで何をしていますか? –

+0

データベースの一部です。私はGUIと同期していません。 – Wodzu

+1

コードが不十分です。スレッド上でFreeを呼び出すと、TerminateとWaitForが呼び出されます。凍結について説明しますか? –

答えて

3

確信を持って何かを言うには十分なコードがありません。ただし、スレッドでFreeを呼び出すと、Terminateが呼び出され、その後にWaitForが呼び出されます。待機が戻ってこないことは、凍ったUIと一貫していると考えられます。

0

これは本当に後方です。まともなスレッドスキームでは、あなたのスレッドはあなたのguiスレッドに.Data.State = fullのような条件について通知します。 gui-threadまたはmain-threadは、適切な処置を行います。私が確信していることの1つは、WorkerThread.Freeが間違っていなければならないということです。何らかの理由で明らかにブロックされたスレッドを解放しようとすると、失敗することが保証されます。スレッドがブロックされていると、Thread.Terminateも失敗するので、そこには何の助けもありません。

タイマーモニタを使用すると、スレッドのステータスが正しくないことがあります。私は決して言葉を使うことは決してありませんが、私は繰り返すでしょう:タイマーモニタをスレッドの状態にすることは、決して正しいことではありません。決してこれまでにない。それについて考えることさえしないでください。

  • トリノ
+0

私は、少なくとも部分的には同意しません。ステータスをチェックするために、タイマーは優先順位の低い良い手段であり、メインスレッドが何をしているかに関係なく、スレッドがビジネスに乗ることを可能にします。しかし、私はこれがここでの貧弱な使用であるということに同意します。これは単にステータスを示すだけでなく、積極的にも制御することです。 – mj2008

+0

@ Turin私はそれがほとんど正しいことに同意します。しかし、私が以前に書いたように、それはレガシーコードであり、タイマーは最初からありました。 – Wodzu