【问题标题】:Why array behaves different when different thread access it为什么数组在不同线程访问时表现不同
【发布时间】:2012-07-11 16:00:25
【问题描述】:

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

注意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();

编辑

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

我认为计数器是问题,但也许我的信号量做错了......

【问题讨论】:

  • 我不明白这个问题。 listToProcess 数组中有 10 个 char 数组。代码正在做它应该做的事情,它将releaseSem 的值设置为true。至于第 11 个元素为 null 的原因是因为您添加了第 10 个元素然后将计数器增加到 10。
  • 对不起,我认为我解释错了问题,因为我认为问题与counter 有关。我更新了你是对的问题。很抱歉没有正确解释我的自我......

标签: c# multithreading performance semaphore


【解决方案1】:

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

含义:你的主张,它设置了

listToProcess[10] = buffer:

不正确:它设置了

listToProcess[9] = buffer:

【讨论】:

  • 谢谢你是对的。我问这个问题的原因是因为在代码的某个时刻我得到一个异常,因为我要阅读的项目是空的。我将在接下来的 20 分钟内进行编辑。非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-17
  • 1970-01-01
  • 2020-04-22
相关资源
最近更新 更多