C#中lock集合后foreach报集合改变错误
错误表现:
多线程中,操作集合(Queue),已经lock集合了,中间使用了一次foreach循环,系统不定时报错
原因分析
foreach循环中,如果集合发送变化,就会报错.
分析解决:
1.测试lock在集合中是否不可用
代码:
public class RunDemo { Queue<string> queue = new Queue<string>(); public void Start() { Thread threa = new Thread(() => { Thread.Sleep(1 * 1000); Console.WriteLine("Thread start"); queue.Enqueue("aaaa"); Console.WriteLine("Thread start111"); queue.Enqueue("bbbb"); }); threa.Start(); lock (queue) { Console.WriteLine("Lock start"); Thread.Sleep(5 * 1000); Console.WriteLine(queue.Count); Console.WriteLine("Lock end"); } } }
运行结果:
结果显示,lock后,子线程依然给集合插入数据
2.解决方法,在插入的时候也先lock一下集合
public class RunDemo { Queue<string> queue = new Queue<string>(); public void Start() { Thread threa = new Thread(()=> { Thread.Sleep(1 * 1000); lock (queue) { Console.WriteLine("Thread start"); queue.Enqueue("aaaa"); Console.WriteLine("Thread start111"); queue.Enqueue("bbbb"); } }); threa.Start(); lock (queue) { Console.WriteLine("Lock start"); Thread.Sleep(5 * 1000); Console.WriteLine(queue.Count); Console.WriteLine("Lock end"); } } }
运行结果:
这时,lock就有用了,再次foreach也不会报错了.
补充说明:
多线程多次LOCK就会表现成单线程情况,这个就需要根据情况抉择了.