Thread synchronization in C# using Monitor Wait/Pulse
<p>I have a multi-threaded project in C# that I'm working on, and my idea for controlling the worker thread is not working out as easily as I hoped.</p>

<p>A thread is created when the main GUI window is launched, here is the function it is running:</p>

<pre><code>    private void continueReading()
    {
        while (true)
        {
            lock (_lock)
            {
                while (!startDAQ)
                    Monitor.Wait(_lock);
                startDAQ = false;
                logging = true;

                daqTaskComponent1.ReadAsync();
            }
        }

    }
</code></pre>

<p>Now, when a button is clicked on the GUI, startDAQ is set to true, and _lock is pulsed to start the thread calling ReadAsync().</p>

<p>On the Async's callback function, I lock the same _lock object and perform some calculations, then set startDAQ to true and pulse again. </p>

<p>This allows my Async function to be called only when the callback is ready to process more data, and that's how it needs to be. </p>

<p>The problem is I need to be able to pause data collection safely, by causing the continueReading thread to pause on the Monitor.Wait and by allowing a callback to complete if ReadAsync has been called before pausing.</p>

<p>This is the code I'm running when the user clicks the button again to pause data collection: </p>

<pre><code>    lock (_lock)
    {
        startDAQ = false;
        Monitor.PulseAll(_lock);
        while (logging)
            Monitor.Wait(_lock);
    }
</code></pre>

<p>This isn't working correctly and I'm getting some deadlocks. This is my first time using Monitor and Wait/Pulsing to signal between threads, so I've been a little stumped, and have a feeling there's an easier way to handle this. Any help or suggestions are appreciated.</p>

<p><strong>EDIT:</strong> Here is the relevant code from the callback function:</p>

<pre><code>    lock (_lock)
    {
        //Lots of code here that just manipulates the data passed to the callback
        startDAQ = true;
        logging = false;
        Monitor.PulseAll(_lock);
    }
</code></pre>

<p>Added the logging boolean that I forgot when I originally pasted my code.</p>
