ConcurrentBagリストを使用してforeachを連続してループしているスレッド#1があり、項目を変更していますが、別のスレッド#2がリストから項目を変更する必要があります。スレッド#2からすべてのオブジェクトを取り出し(一方がforeachでループしている間に)、オブジェクトを変更してスレッド#2のすべてのアイテムを追加しても安全ですか?それが解決しない場合は回避策がありますか?別のスレッドからConcurrentBagオブジェクトを変更する
ConcurrentBag<MyObject> list;
スレッド1
while (1) // continuous loop
{
foreach(MyObject obj in list)
{
obj.RunMethod();
Thread.Sleep(500);
}
Thread.Sleep(1000);
}
スレッド2
(いくつかの点でコールバックがスレッド#2に呼び出され、オブジェクトを変更する必要があることである)
List<MyObject> temp;
while (list.TryTake(out obj)
{
MyObject obj2=obj.Clone(); // make a copy of the object
if (obj2.Id==4) obj2.variable=10;
temp.Add(obj2);
}
// Add objects back to concurrentbag
foreach(MyObject obj in temp) list.Add(obj);
なぜすべてのアイテムを取り出して読み込む必要がありますか? – Evk
そうすることで、どんな問題を解決しようとしていますか?コンテキストがなければ、2つのスレッドが同じオブジェクトを同時に変更しようとするのが安全かどうかを知ることは難しいです(ただし、ConcurrentBagを使用すると未定義の動作は発生しません)。 –
ConcurrentBagはスレッドごとにコレクションを作成するので、アイテムを追加すると、現在のスレッドに属するコレクションに追加されます。オブジェクトを取り出すと、まずコレクションを空にしてから、他のスレッドのコレクションからオブジェクトを盗み始めます。それはスレッドセーフな方法で盗み出しますので、これは安全です。私はこれがあなたが解決している問題を探している解決策ではないと考えています。それを行うより良い方法があります。私達に情報を与え、あなたが何をすべきかアドバイスすることができます。 – john