C# 并发列表访问

本文关键字:访问 列表 并发 | 更新日期: 2023-09-27 18:32:19

有这个类,它允许在一个线程中将数据写入流并在多个线程中读取。

它的主要目的是支持流媒体,例如网络或音频流,读取它并在多个线程中处理,允许数据随之而来。

http://www.codeproject.com/Articles/345105/Memory-Stream-Multiplexer-write-and-read-from-many?msg=4665022#xx4665022xx

MemoryStreamMultiplexer逐块写入数据块并存储到List<byte[]> _Buffer变量中。

然后将此_Buffer传递到 MemoryStreamReader 中,如下所示:

new MemoryStreamReader(_Buffer, dataReady, finished);

MemoryStreamReader 读取存储在此_Buffer列表中的 byte[] 数组,检查数据是否存在

if (_bufferIndex < _bufferList.Count)
{
  return ReadInternal(buffer, offset, count);
}

ReadInternal 从列表中获取下一个缓冲区_Buffer然后读取它

byte[] currentBuffer = _bufferList[_bufferIndex];

现在,问题来了:在随机情况下,currentBuffer 变为 null,这会导致稍后的 NullReferenceException。

在调试中,虽然 currentBuffer 被声明为 null,但如果我检查 _bufferList[_bufferIndex] 中的值 - 返回有效的数组。所以这似乎是一些内存或并发问题。

我的想法是,在某个时候,List决定改变它的容量,重新分配内部数组。当我们仍在读取列表时,它返回 null,因为内存地址已经更改,但尚未将数据复制到其中。

问题是 - 如何解决此问题?

C# 并发列表访问

这是一个稍微扩展的生产者-消费者问题。

由于您使用的是 C#(gc,内存将自动释放),我建议使用单独的同步队列创建每个使用者,然后将相同的数据数组发布到每个队列中。由于数据在推送后才会被读取,因此多个线程同时访问它是完全安全的。

使用 ConcurrentQueue 将使您不必担心同步,从而为您节省大量工作。