3

私のプログラムでは、カタログをロードできます:ICatalog

ここのカタログには、参照カウントされた構造体が多数含まれています (IItems、IElements、IRules などの Icollections)。

別のカタログに変更したい場合、新しいカタログをロードしますが、以前の ICatalog インスタンスの自動リリースには時間がかかり、アプリケーションが 2 秒以上フリーズします。

私の質問は:

古い (そしてもう使用されていない) ICatalog インスタンスのリリースを別のスレッドに延期したいと考えています。

まだテストしていませんが、新しいスレッドを作成するつもりです:

ErazerThread.OldCatalog := Catalog; // old catalog refcount jumps to 2
Catalog := LoadNewCatalog(...);     // old catalog refcount =1
ErazerThread.Execute;               //just set OldCatalog to nil.

このようにして、リリースがスレッドで発生し、アプリケーションがフリーズしないことを期待しています。

それは安全ですか(そして良い習慣ですか)?
同様の方法ですでにリリースを実行している既存のコードの例はありますか?

4

2 に答える 2

2

問題ないように見えますが、スレッドのExecuteメソッドを直接呼び出さないでください。これにより、スレッド オブジェクトが作成するスレッドではなく、現在のスレッドでスレッド オブジェクトのコードが実行されます。StartまたはResume代わりに呼び出します。

于 2011-10-19T14:53:37.140 に答える
2

そのようなスレッドをいくつかのスレッドセーフ キュー (*) でブロックさせ、インターフェイスをプッシュして、iunknowns としてそのキューに解放します。

ただし、解放がメモリ マネージャーが使用するロック (グローバル ヒープマネージャー ロックなど) に触れる場合、メインスレッドが最初のヒープマネージャー アクセスでブロックされるため、これは無駄であることに注意してください。

スレッドごとのプールを持つヒープマネージャーを使用すると、1 つのスレッドに多くの項目を割り当てて別のスレッドで解放すると、(小さな) ブロック アルゴリズムの合体と再利用が妨げられる可能性があります。

あなたが説明する方法は、適切に実装されていれば、一般的に健全だと思います。ただし、これは、ヒープマネージャーを介して 2 番目のスレッドからメインスレッドへのリンクが存在する可能性があることを示す理論的な観点からのものです。

(*) 最も簡単な方法は、それを tthreadlist に追加し、tevent を使用して要素が追加されたことを通知することです。

于 2011-10-19T16:55:50.010 に答える