優れたOmniThreadLibraryライブラリを使用して、スレッド化されたソースコードの解析を実装します。プログラムは、既存の解析を破棄し、ソースコードが変更されるたびに解析を再開する必要があります。
以下に示すコードスニペットを使用してこれを行いますが、正しい方法ですか?関数Terminated
内のスレッドのプロパティを確認する必要がありますか?ThreadedParseHtml
if FParserThread <> nil then
begin
FParserThread.RemoveMonitor;
FParserThread.Terminate(500);
end;
FParserThread := CreateTask(ThreadedParse);
FParserThread.SetParameter('SourceCode', Editor.Lines.Text);
FParserThread.MonitorWith(FParserThreadMonitor);
FParserThread.Run;
前もって感謝します!
編集1FParserThread
:この質問を再度開いて申し訳ありませんが、十分な時間をかけてメソッドを呼び出して、それ自体で完了しないとメモリリークが発生することがわかりましTerminate
た...メモリリークの原因について何か考えはありますか?ありがとう!
編集2 :このブログ投稿を読んでくださいThreadedParse
。コードのすべてのステップの後で問題が発生した場合Terminated
は中断するため、問題が何であるかはまだわかりません。
編集3:ロブの質問に答える:
OnTerminatedイベントハンドラー(ここには表示されていません)では、FParserThreadは「nil」に設定されているため、「FParserはそれ自体で完了します」とは、
if FParserThread <> nil then
ブロックが実行されないことを意味します。この場合、FParserThreadは、解析が完了したために終了します。コードの背後にあるロジックは、これがコードエディターであり、コードを編集すると、新しいコード編集が発生したが前の解析が行われた場合に、ソースコードを内部ツリープレゼンテーションに解析するためのスレッドが開始されるというものです。編集されていない場合、プログラムは最初に前の解析スレッドを強制的に開始し、次に新しい解析スレッドを開始します。これはおそらく良いアプローチではありません...
編集4 :この同様のSO質問を読んだ後、パラメーターなしで呼び出すようにコードを変更しましFParserThread.Terminate
た。つまり、正しく理解していれば、そのステートメントはスレッドに終了を通知するだけであり、実際のスレッドタスク内でロジックを適用しました。Terminated
プロパティが。の場合は、スレッドの実行を終了しますTrue
。
これで、 Tracetoolの助けを借りて、イベント(メモリをクリーンアップする場所)を呼び出しFParserThread.Terminate
た後OnTaskMessage
、再度起動されないことがわかりました。これがメモリリークの原因でした。