snickesnack snickesnack - 20 days ago 5
C# Question

Synchronizing a buffer in C#

So I'm new to both C# and working with multiple threads. I got this application which has 2 classes, writer and reader which both have a reference to my CharacterBuffer class. So I input a string to the program, and the writer should read the chracters to the buffer, and the reader read from the buffer, all synchronized. This is the buffer class:

public class CharacterBuffer
{
private static object Lock = new object();
private Queue result;

public CharacterBuffer()
{
result = new Queue();
lock (result);
}

public void addChar(char c)
{
result.Enqueue(c);
Monitor.PulseAll(result);
}

public char readChar()
{
Monitor.Wait(result);
return (char) result.Dequeue();
}
}


So what I think I am doing is first I declare the queue and put a lock unto it. So when the reader calls readChar() it will have to wait until the writer has called addChar(char c). But whenever I start the reader and writer thread, it instantly throws an exception
'System.Threading.SynchronizationLockException' occurred in mscorlib.dll


Obviosuly I'm doing something wrong. I have searched for an answer and it seems that the code block calling Monitor have to make all the calls in the same block. Beacuse in this case, my separate threads are calling it instead of the Buffer itself. So the question is; what to do instead?

Answer

If you are concerned about queue modified in multiple threads, please use following code:

public class CharacterBuffer
{
    private static object padlock = new object();
    private Queue result;

    public CharacterBuffer()
    {
        lock (padlock)
        {
            result = new Queue();
        }
    }

    public void AddChar(char c)
    {
        lock (padlock)
        {
            result.Enqueue(c);
        }
    }

    public char ReadChar()
    {
        lock (padlock)
        {
            return (char) result.Dequeue();
        }
    }
}
Comments