J'ai une classe qui hérite de MemoryStream afin de fournir une mise en mémoire tampon. La classe fonctionne exactement comme prévu mais de temps en temps j'obtiens une exception InvalidOperationException pendant une lecture avec le message d'erreur étantLe verrouillage d'une liste peut-il échouer
La collection a été modifiée; l'opération d'énumération peut ne pas s'exécuter.
Mon code est ci-dessous et la seule ligne qui énumère une collection semblerait être:
m_buffer = m_buffer.Skip(count).ToList();
Cependant, je dois cela et toutes les autres opérations qui peuvent modifier l'objet m_buffer dans les serrures, donc je suis mystifié quant à la façon dont une opération d'écriture pourrait interférer avec une lecture pour provoquer cette exception?
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;
}
}
}
}
C'est en effet une erreur, mais cela ne devrait pas entraîner l'exception InvalidOperationException. – SoftMemes
Oui, ce ne sera pas le cas. C'est pourquoi j'ai dit "au moins un". Ce que vous avez mentionné dans votre réponse est très probablement à l'origine de ce problème. –
Si j'attends dans la méthode Read contenant le verrou, comment pourrais-je acquérir le verrou dans la méthode Write? – sipwiz