2

我正进入(状态:

此行中的“集合已修改枚举操作可能无法执行”:

foreach (Message msg in queue)

过了一会儿。

我必须使用 .NET 2.0。

我对名为“queue”的私有 List<> 进行的两个操作如下:

// 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 回答