2

私は得ています:

このllineで「コレクションが変更された列挙操作が実行されない可能性があります」:

foreach (Message msg in queue)

しばらくして。

.NET2.0を使用する必要があります。

「queue」という名前のプライベートリスト<>で行う2つの操作は次のとおりです。

// 1st function calls this
lock (queue)
{
      queue.Add(msg);
}

// 2nd function calls this
lock (queue)
{
      using (StreamWriter outfile = new StreamWriter("path", true)
      {
             foreach (Message msg in queue) // This is were I get the exception after a while)
             {
                  outfile.WriteLine(JsonConvert.SerializeObject(msg)); 
             }

              queue = new List<Message>();
      }
}

私は何が間違っているのですか?

4

2 に答える 2

3

(以下;まあ、これを引き起こす競合状態を思い付くことができません...しかし:誰が知っていますか...)

まず、リストと通信する他のコードを探す必要があります問題はあなたが投稿するコードにはありません。どうすればこれを知ることができますか?foreach (Message msg in queue)( )を列挙している時点で、がロックされqueueており、ロックオブジェクトの(非常に危険ですが無関係な)再割り当てについては何もしていません。

これforeachがエラーになるということは、他の何かがリストを変更していることを意味します。最初に行うことは、非常に簡単に、リストフィールドの名前を変更することです。これにより、他のコードがリストに含まれているかどうかがすぐにわかります。また、このコードの外部にリストを公開return queue;しないように、つまりどこからも公開しないようにしてください。

表示されているコードに問題はないようです。ロックオブジェクトの再割り当ては悪い習慣であり、そうすべきではありません-しかし:実際にそれを壊すシナリオ(コードが示されている)はわかりません。


ここではリストは最適なモデルではなく、ロックオブジェクトを再割り当てすることはお勧めできません。キューを表すように設計された組み込みタイプがあれば...

private readonly Queue<Message> queue = new Queue<Message>();
...
lock (queue) {
    queue.Enqueue(msg);
}

// 2nd function calls this
lock (queue) {
    if(queue.Count == 0) continue; // taken from comments

    using (StreamWriter outfile = new StreamWriter("path", true) {
        while(queue.Count != 0) {
            Message msg = queue.Dequeue();
            outfile.WriteLine(JsonConvert.SerializeObject(msg)); 
        }
    }
}

クリアする必要はありませんDequeue。それは本質的かつ効率的に行われるからです。

于 2012-06-07T09:40:40.577 に答える
1

lickステートメントで使用されるパラメーターは読み取り専用である必要があります。このリンクを参照してください

readonly private objectの代わりに使用queqe

コードは

eadonly object _object = new object();
// 1st function calls this
lock (_object)
{
      queue.Add(msg);
}

// 2nd function calls this
lock (_object)
{
      using (StreamWriter outfile = new StreamWriter("path", true)
      {
             foreach (Message msg in queue) // This is were I get the exception after a while)
             {
                  outfile.WriteLine(JsonConvert.SerializeObject(msg)); 
             }

              queue = new List<Message>();
      }
}
于 2012-06-07T09:33:56.737 に答える