可以锁定列表失败

sip*_*wiz 2 c# locking

我有一个继承自MemoryStream的类,以提供一些缓冲.该类的工作方式完全符合预期,但在读取过程中我偶尔会收到InvalidOperationException,并显示错误消息

收集被修改; 枚举操作可能无法执行.

我的代码在下面,枚举集合的唯一行似乎是:

m_buffer = m_buffer.Skip(count).ToList();
Run Code Online (Sandbox Code Playgroud)

但是我有这个以及所有其他可以在锁内修改m_buffer对象的操作,所以我对于Write操作如何干扰Read导致该异常感到困惑?

public class MyMemoryStream : MemoryStream
{
    private ManualResetEvent m_dataReady = new ManualResetEvent(false);
    private List<byte> m_buffer = new List<byte>();

    public override void Write(byte[] buffer, int offset, int count)
    {
        lock (m_buffer)
        {
            m_buffer.AddRange(buffer.ToList().Skip(offset).Take(count));
        }
        m_dataReady.Set();
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
        if (m_buffer.Count == 0)
        {
            // Block until the stream has some more data.
            m_dataReady.Reset();
            m_dataReady.WaitOne();
        }

        lock (m_buffer)
        {
            if (m_buffer.Count >= count)
            {
                // More bytes available than were requested.
                Array.Copy(m_buffer.ToArray(), 0, buffer, offset, count);
                m_buffer = m_buffer.Skip(count).ToList();
                return count;
            }
            else
            {
                int length = m_buffer.Count;
                Array.Copy(m_buffer.ToArray(), 0, buffer, offset, length);
                m_buffer.Clear();
                return length;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Sof*_*mes 5

我不能确切地说你发布的代码出了什么问题,但有点奇怪的是你锁定了m_buffer,但是替换了缓冲区,因此锁定的集合并不总是被读取和修改的集合.

优良作法是使用专用的私有只读对象进行锁定:

private readonly object locker = new object();

    // ...
    lock(locker)
    {
         // ...
    }
Run Code Online (Sandbox Code Playgroud)