首页 > 解决方案 > 从列表中添加和删除时出现“索引超出范围”错误

问题描述

我想向列表中添加/删除,但出现“索引超出范围”异常。在我的代码中,我在一秒钟内添加数据 2 次,直到 10 次。我使用线程将它们删除。我也使用信号量进行阻塞。我想同时使用 3 个线程。

这是我的代码

 class Program
{
    private static Thread[] threads = new Thread[3];
    private static Semaphore sem = new Semaphore(3, 3);
    private static List<string> messagesList = new List<string>();
    private static readonly object _kilit = new object();
    static void Main(string[] args)
    {
        Thread addData = new Thread(AddData);
        addData.Start();

        for (int j = 0; j < 3; j++)
        {
            threads[j] = new Thread(AddComma);
            threads[j].Name = "thread_" + j;
            threads[j].Start();
        }
    }
    public static void AddData()
    {

        for (int i = 0; i < 10; i++)
        {

            messagesList.Add("data");
            messagesList.Add("data");                
            Thread.Sleep(1000);

        }

    }
    public static void AddComma()
    {
        sem.WaitOne();
        while (true) {                
            if (messagesList.Count > 0)
            {

                    Console.WriteLine();
                    Console.WriteLine(Thread.CurrentThread.Name + "Entering to Critical section");
                    int averageIndex = messagesList[0].ToString().Length / 2; // Here is the error
                    string msg = messagesList[0].ToString().Substring(0, averageIndex) + "," + messagesList[0].ToString().Substring(averageIndex);
                    Console.WriteLine(msg);
                    messagesList.RemoveAt(0);
                    Console.WriteLine(Thread.CurrentThread.Name + "Exiting from Critical Section");                                   

            }             
        }
        sem.Release();

    }
}

标签: c#multithreadinglist

解决方案


您允许三个线程同时运行:

new Semaphore(3, 3);

所以你Semaphore并没有真正帮助你,因为你并没有真正阻止。因此,您仍然会遇到问题,例如,您可能会在列表中留下一条消息,但 3 个线程都评估messagesList.Count > 0true. 其中一个线程将首先从列表中删除该项目,这将导致其他两个抛出异常。

有更好的方法来做到这一点。对于列表,我喜欢使用ReaderWriterLockSlim具有读锁和写锁的 。它允许所有线程读取,但一旦您获得写入锁,就会阻止所有人。文档中有一个如何使用它的示例。


推荐阅读