为了处理快速填充的大型数组中的数据,我创建了几个线程来并行处理它。删除第一个元素和记录结果必须同步,因此我使用了 AutoResetEvent。 问题是,在某些时候,当删除元素时,它会抛出一个错误,即 0 索引超出范围,即使其中有元素。我不知道这是怎么发生的。
private void InitializeProcessingThreads()
{
for (int i = 0; i < numberOfThreads; i++)
{
ares[i] = new AutoResetEvent(false);
int index = i;
threads[i] = new Thread(() =>
{
try
{
while (true)
{
if (BigArray.Count < index + 1)
{
Debug.WriteLine("BigArray is smaller than " + (index + 1));
continue;
}
byte[] data = BigArray[index];
Processing(data);
// do other processing here
if (index > 0)
{
ares[index - 1].WaitOne();
}
else
{
ares[numberOfThreads - 1].WaitOne();
}
Debug.WriteLine(Thread.CurrentThread.Name + " Completed processing");
if (BigArray.Count != 0)
BigArray.RemoveAt(0); // Or call another thread to remove all the packets and do some general work
ares[index].Set();
if (index > 0)
{
ares[index - 1].Reset();
}
else
{
ares[numberOfThreads - 1].Reset();
}
}
}
catch (Exception e)
{
Debug.WriteLine(Thread.CurrentThread.Name + ", " + BigArray.Count + ", " + e);
throw;
}
});
threads[i].Name = "Thread" + i;
}
ares[numberOfThreads - 1].Set();
}
这个循环永远运行。
我不知道这是怎么发生的。我尝试仅在数组大小不为零时删除元素,但它仍然运行并给出错误。
看来您需要使用另一种解决方案来完成您的任务。不要删除元素,而是将数组用作循环缓冲区,其中包含指向第一个元素和最后一个元素的指针。
这不仅可以缓解您所描述的问题,还可以提高生产力。