私は、今後の.NET 4.0フレームワークでConcurrentBag<T>
クラスの存在によって、自分自身が非常に興味をそそら見つける:.NETのConcurrentBag <T>のようなクラスはどのように実装できますか?
バッグは、順序は重要ではありませんオブジェクトを格納するために有用であり、セットとは異なり、バッグは重複をサポートしています。
質問:このアイデアはどのように実装されますか?私がよく知っているほとんどのコレクションは、本質的には、配列のいくつかの形で、「重要」ではないかもしれませんが、はです(これは、列挙は、同じシーケンス内のList
、Queue
、Stack
などと変わらないコレクションをほとんど常に通ります。
私が推測しなければならないことは、内部的にはDictionary<T, LinkedList<T>>
である可能性があります。実際にはのいずれかタイプT
をキーとして使用することは理にかなっていないと考えて、実際はかなり疑わしいようです。
私が期待しているのは、これが実際には既にどこかで「考え出された」確立されたオブジェクトタイプであり、この確立されたタイプを知っている誰かがそれについて教えてくれるということです。実生活では理解しやすいが、開発者として利用可能なクラスに変換するのは難しいという概念のひとつであり、私はその可能性について好奇心が強いのです。
EDIT:
一部レスポンダはBag
が内部ハッシュテーブルの形かもしれないことを示唆しています。これは私の最初の考えでもありましたが、私はこの考え方に2つの問題があると予期しました:
- 問題のタイプに適切なハッシュコード関数がないときにハッシュテーブルが役立つわけではありません。
- コレクション内のオブジェクトの「カウント」を単に追跡することは、オブジェクトを格納することと同じではありません。
メタナイトが示唆したように、おそらく例これは、より明確になるだろう:
public class ExpensiveObject() {
private ExpensiveObject() {
// very intense operations happening in here
}
public ExpensiveObject CreateExpensiveObject() {
return new ExpensiveObject();
}
}
static void Main() {
var expensiveObjects = new ConcurrentBag<ExpensiveObject>();
for (int i = 0; i < 5; i++) {
expensiveObjects.Add(ExpensiveObject.CreateExpensiveObject());
}
// after this point in the code, I want to believe I have 5 new
// expensive objects in my collection
while (expensiveObjects.Count > 0) {
ExpensiveObject expObj = null;
bool objectTaken = expensiveObjects.TryTake(out expObj);
if (objectTaken) {
// here I THINK I am queueing a particular operation to be
// executed on 5 separate threads for 5 separate objects,
// but if ConcurrentBag is a hashtable then I've just received
// the object 5 times and so I am working on the same object
// from 5 threads at the same time!
ThreadPool.QueueUserWorkItem(DoWorkOnExpensiveObject, expObj);
} else {
break;
}
}
}
static void DoWorkOnExpensiveObject(object obj) {
ExpensiveObject expObj = obj as ExpensiveObject;
if (expObj != null) {
// some work to be done
}
}
+1このクラスの存在を知っておいてよろしいですか? – Konamiman
Dan-o:あなたのサンプルコードの5行のコメントは意味がありません。もちろん、あなたはその時点でそのバッグに5つの独立したオブジェクトを持っています。[public ExpensiveObject CreateExpensiveObject()]の "new"演算子はそれを保証します。 – Boogaloo
mmm。私の間違い。私は過去にハッシュを使用していません。私は、デフォルトのハッシュ・ジェネレータがオブジェクトごとに一意のハッシュ値を作成すると仮定していました。これは独自のハッシュ・ジェネレータでオーバーライドできます。私を気にしないでください。 :) – Boogaloo