当不同的线程访问它时,为什么数组的行为不同

时间:2012-07-11 16:00:26

标签: c# multithreading performance semaphore

我需要解析类似于XML的大文本。因为它不在内存中的文本(我有一个StreamReader对象)将该流放在内存中是我花费最多时间的地方。所以在一个线程上我将该流放入一个数组(内存)。我有另一个处理该数组的线程。但我有很奇怪的行为。例如,看看这张图片:

enter image description here

请注意,listToProcess[counter] = buffer现在应该是listToProcess[10] = buffer请注意调试器说listToProcess[10]=null为什么!? 。另一个线程只读取它不修改它们的项目。起初我以为可能另一个线程正在使该item = null但事实并非如此。为什么我会遇到这种行为?


如果您想在此处查看我的代码,请执行以下操作:

        Semaphore sem = new Semaphore(0, 1000000);
        bool w;
        bool done = false;

        // this task is responsible for parsing text created by main thread. Main thread
        // reads text from the stream and places chunks in listToProces[]
        var task1 = Task.Factory.StartNew(() =>
        {
            sem.WaitOne(); // wait so there are items on list (listToProcess) to work with                
                                // counter to identify which chunk of char[] in listToProcess we are ading to the dictionary
                int indexOnList = 0;

                while (true)
                {
                    if (listToProcess[indexOnList] == null)
                    {
                        if (done)
                            break;

                        w = true;
                        sem.WaitOne();
                        w = false;



                        if (done)
                            break;

                        if (listToProcess[indexOnList] == null)
                        {
                            throw new NotFiniteNumberException();
                        }
                    }

                    // add chunk to dictionary
                    ProcessChunk(listToProcess[indexOnList]);

                    indexOnList++;
                }

        }); // close task1

        bool releaseSem = false;

        // this main thread is responsible for placing the streamreader into chunks of char[] so that
        // task1 can start processing those chunks
        int counter = 0;
        while (true)
        {
            char[] buffer = new char[2048];

            // unparsedDebugInfo is a streamReader object
            var charsRead = unparsedDebugInfo.Read(buffer, 0, buffer.Length);

            if (charsRead < 1)
            {
                listToProcess[counter] = pattern;
                break;
            }

            listToProcess[counter] = buffer;
            counter++;

            if (releaseSem)
            {
                sem.Release();
                releaseSem = false;
            }

            if (counter == 10 || w)
            {
                releaseSem = true;
            }
        }

        done = true;

        sem.Release();
       task1.Wait();

修改

对不起,换句话说为什么我会点击这个断点:

enter image description here

我认为反问题是问题,但也许我对信号量做错了......

1 个答案:

答案 0 :(得分:7)

您有一个counter++,因此您在之前更新的位于索引9,而不是索引10.

含义:您声称已设置

listToProcess[10] = buffer:

不正确:设置

listToProcess[9] = buffer: