Question

In the past, I have been using a BinaryReader to read a few bytes, but recently, I have gotten this error:

An error has occurred: Probable I/O race condition detected while copying memory. The I/O package is not thread safe by default. In multithreaded applications, a stream must be accessed in a thread-safe way, such as a thread-safe wrapper returned by TextReader's or TextWriter's Synchronized methods. This also applies to classes like StreamWriter and StreamReader.    at System.Buffer.InternalBlockCopy(Array src, Int32 srcOffset, Array dst, Int32 dstOffset, Int32 count)
   at System.IO.FileStream.Read(Byte[] array, Int32 offset, Int32 count)
   at System.IO.BinaryReader.FillBuffer(Int32 numBytes)
   at System.IO.BinaryReader.ReadUInt16()

So, as a result I have decided to use TextReader's Synchronized methods like the following:

public class SafeReader
{
    private Stream m_Stream;
    private TextReader m_TextReader;
    public SafeReader(Stream stream)
    {
        m_TextReader = TextReader.Synchronized(new StreamReader(m_Stream = stream));
    }
    public Stream BaseStream
    {
        get { return m_Stream; }
    }
    public int ReadInt32()
    {
        // this doesn't even need to do anything (just has to read 4 bytes and it gets disposed of anyway);
        ReadUInt16();
        ReadUInt16();
        return -1;
    }
    public short ReadInt16()
    {
        return (short)(this.ReadUInt16());
    }
    public ushort ReadUInt16()
    {
        return BitConverter.ToUInt16(new byte[] { (byte)(m_TextReader.Read() & 0xFF), (byte)(m_TextReader.Read() & 0xFF) }, 0);
        //return (ushort)(((m_TextReader.Read() & 0xFF)) | ((m_TextReader.Read() & 0xFF) << 8));
    }
}

However, the values returned (it pretty much reads an image in a proprietary format) is incorrect. The "images" have a slight bluish hue and I have a feeling this could be caused by the fact that TextReader reads text (and reads chars with an encoding instead of just reading the byte values).

Is there a "thread-safe" way like TextReader's Synchronized() to read binary files?

Was it helpful?

Solution

You should be able to useBinaryReaderinstead of TextReader. Just make sure you lock the array on the thread you access it from (writing).

Object locker = new Object;

lock (locker) {
    //BinaryReader here
}

From the other thread(s) use the same:

lock (locker) {
    //read from array (read is thread-safe though)
}

If there is a write-operation going on the other thread will wait until the object is unlocked.

You can also use the File.ReadAllBytes if you don't need to read in chunks.

Alternatively use ASCII or UTF8 encoding with the Textreader.

OTHER TIPS

Try File.ReadAllBytes(). Then you could use a MemoryStream to extract values out of the buffer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top