多くの非同期スレッドがグローバル TBitmap を描画すると、エラーが発生しますか? クリティカル セクションを使用してコードを作成する必要がありますか? (インターネットでのサーフィンから、TBitmap.Draw はスレッドセーフではないことがわかりました)
別の質問: 多くの同期スレッドがグローバル TBitmap を描画し、VCL タイマーが TBitmap からコンテンツを非同期的に読み取る場合、エラーが発生しますか?
ありがとう!
多くの非同期スレッドがグローバル TBitmap を描画すると、エラーが発生しますか? クリティカル セクションを使用してコードを作成する必要がありますか? (インターネットでのサーフィンから、TBitmap.Draw はスレッドセーフではないことがわかりました)
別の質問: 多くの同期スレッドがグローバル TBitmap を描画し、VCL タイマーが TBitmap からコンテンツを非同期的に読み取る場合、エラーが発生しますか?
ありがとう!
TBitmap
はい、複数のスレッドにまたがる同時アクセスから保護する必要があります。図面コードをシリアル化するにはクリティカルセクションで十分ですが、それだけでは十分ではありません。メインスレッドはGDIリソースをキャッシュし、定期的にクリーンアップを実行します。これは、に影響しますTBitmap
。そのため、VCLがリソースを背後から奪わないようにするために、描画/レンダリングをLock/Unlock()
行う必要があります。TBitmap.Canvas
スレッドはすべて同じビットマップを変更しているため、そのビットマップへのすべてのアクセスをシリアル化する必要があります。つまり、その内容を読み取るだけでなく、書き込むことも意味します。
もちろん、これは、共有ビットマップに描画する複数のスレッドが問題の正しい解決策であることを前提としています。あなたの実際の問題が何であるかを知らずに、私はそれについてコメントすることができませんでした。
アップデート
Remyの回答Lock/Unlock
で説明されている問題があるため、ビットマップに描画するときにも使用する必要があります。これは、この質問に対する受け入れられた答えであるはずです。
モニターまたはセマフォを使用して、スレッドが TBitmap Pixels を変更するときにスレッドを制御してください。
代わりにTThread.Synchronizeメソッドを使用できますか?
TThreadクラスのドコによると
以下は、スレッドを使用するときに注意すべき問題と推奨事項です。
あまりにも多くのスレッドを追跡すると、CPU時間が消費されます。推奨される制限は、シングルプロセッサシステムのプロセスごとに16のアクティブスレッドです。
複数のスレッドが同じリソースを更新する場合、競合を回避するためにそれらを同期する必要があります。
オブジェクトにアクセスしてフォームを更新するほとんどのメソッドは、メインスレッド内からのみ呼び出すか、TMultiReadExclusiveWriteSynchronizerなどの同期オブジェクトを使用する必要があります。