我得到了:
“集合被修改的枚举操作可能无法执行”在此行:
foreach (Message msg in queue)
过了一会儿。
我必须使用.NET 2.0。
我在私人列表<>上进行的两项操作名为“队列”的如下:
// 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>();
}
}
我做错了什么?
答案 0 :(得分: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
具有内在和有效的功能。
答案 1 :(得分:1)
lick语句使用的参数应该是readonly。见link
使用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>();
}
}