ConcurrentBag<T>
次の .NET 4.0 フレームワークに次のようなクラスが存在することに、私は非常に興味をそそられています。
バッグは、順序が重要でない場合にオブジェクトを格納するのに役立ちます。また、セットとは異なり、バッグは複製をサポートします。
私の質問は次のとおりです。このアイデアをどのように実装できますか? 私がよく知っているほとんどのコレクションは、本質的に (ボンネットの下で) 何らかの形式の配列に相当し、その順序は「重要」ではないかもしれませんが、順序があります (これが、その必要がないにもかかわらず、列挙が行われる理由です)。ほとんどの場合、変更されていないコレクション ( List
、Queue
、Stack
など) を同じ順序で処理します)。
Dictionary<T, LinkedList<T>>
推測する必要がある場合は、内部的には;になる可能性があることをお勧めします。しかし、キーとして任意のタイプを使用するのは意味がないことを考えると、それは実際にはかなり疑わしいようです。T
私が期待/期待しているのは、これが実際にはすでにどこかで「理解されている」確立されたオブジェクトタイプであり、この確立されたタイプを知っている誰かがそれについて教えてくれることです。これは私にとって非常に珍しいことです。実生活で理解するのは簡単ですが、開発者として使用可能なクラスに変換するのは難しい概念の 1 つです。そのため、可能性について興味があります。
編集:
Bag
一部の回答者は、aが内部的にハッシュテーブルの形式である可能性があることを示唆しています。これは私の最初の考えでもありましたが、この考えには 2 つの問題があることを予見しました。
- 問題のタイプに適したハッシュコード関数がない場合、ハッシュテーブルはそれほど役に立ちません。
- コレクション内のオブジェクトの「カウント」を単に追跡することは、オブジェクトを格納することと同じではありません。
Meta-Knight が示唆したように、おそらく例はこれをより明確にするでしょう:
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
}
}