11

基本的に、スレッド内のカメラから取得した画像コレクションのコンテナーを探しています。ConcurrentQueue はスレッドセーフなので、それを使いたかったのです。しかし、コードをデバッグしているときに、この記事が言っているのを見つけました

要素が小さい場合、おそらくこれに気付かないでしょう。ただし、要素が大きなリソースを保持している場合 (たとえば、各要素が巨大な画像ビットマップである場合)、この影響が見られる可能性があります (回避策の 1 つは、ラッパー オブジェクトをキューに入れること ConcurrentQueue<StrongBox<T>>ですConcurrentQueue<T>。ラッパーがキューから取り出された後、T 値へのラッパーの参照を出力します)。

私が見る限り、StrongBox元の値の一種のラッパーです。別の画像コレクションを保存する必要があるということですか?

だから私は使用法または例を探していますConcurrentQueue<StrongBox<T>>.Googleから見つけたのはこのコードだけです。

4

1 に答える 1

8

時期尚早の最適化の危険性はコメントに記載されているので、ここで何が起こっているかのセマンティクスについて説明します。

記事が指摘しているようにConcurrentQueue、 はすでにそれを通過したいくつかの参照を保持できます。私はそれを「数ダース」と学びましたが、記事にはそれが 31 以下であると書かれています。キューが 2000x2000 ビットマップのような大きなオブジェクトを追跡している場合、理論的には問題になる可能性があります。もちろん、プログラムの残りの部分が何をしているかによって異なります。

StrongBox<T>唯一のことStrongBoxは他の何かへの参照を保持することであるため、それを a でラップすると役立ちます。したがって、 a のStrongBoxフットプリントは非常に小さく、それが保持するものはすべて範囲外になり、(理論的には) より迅速に GC されます。

ダイエットソーダのすべての内容を持っているのでStrongBox、あなたはその使用法を考えすぎています. 文字通り、ValueフィールドにいくつかTをロードして、後で参照するだけです。次のようになります。

var boxedBitmap = new StrongBox<Bitmap>(new Bitmap(1,1));
var bitmap = boxedBitmap.Value;

または、次のようにします。

var boxedBitmap = new StrongBox<Bitmap>();
boxedBitmap.Value = new Bitmap(1,1);
var bitmap = boxedBitmap.Value;

真剣に、Reflector で開くと、このクラスの実装は 5 行のようになります。

この場合、 の使用法はConcurrentQueue<T>の使用法とまったく違いはありませんConcurrentQueue<StrongBox<T>>.Valueリソースを宛先スレッドに送信する前に、追加するだけです。これは、私が働いていた会社が、ツール全体を渡すのではなく、決定論的ツールへの参照を渡すだけで、大規模なマルチスレッド分析サービスのメモリインプリントをかなり削減するのに役立ちましたが、マイレージは異なる場合があります-明確ではありません何かを変更して別のものに使用するために渡した場合、どのような影響があるかについて。

于 2012-11-28T21:58:03.217 に答える