我需要解析类似于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();
对不起,换句话说为什么我会点击这个断点:
我认为反问题是问题,但也许我对信号量做错了......
答案 0 :(得分:7)
您有一个counter++
,因此您在之前更新的位于索引9,而不是索引10.
含义:您声称已设置
listToProcess[10] = buffer:
不正确:设置
listToProcess[9] = buffer: