置百丈玄冰而崩裂,掷须臾池水而漂摇。

C#中lock集合后foreach报集合改变错误

ASP.NET 强强

错误表现:

多线程中,操作集合(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就会表现成单线程情况,这个就需要根据情况抉择了.

发表评论:

验证码