folmerbrem
folmerbrem

Reputation: 41

Can a blocked thread fire events?

I have a program that spawns a thread controlling a serial communication. While it waits for response on the serial port, I block the thread with a AutoResetEvent.

Will that thread be unable to execute the event when data is received because it is blocked?

To illustrate the point I have a simple version of my code below. Will this code result in a deadlock or can an event run in a blocked thread, eventually waking up itself?

AutoResetEvent rxDataReady = new AutoResetEvent(false);

public void GetSomeDataFromSerialPort()
{
    SerialPort sp = new SerialPort()
    sp.Write(dataRequest)

    rxDataReady.WaitOne();

    // Process data
}

private void ReadDataEventHandler(object sender, SerialDataReceivedEventArgs e)
{
    // Prepare data
    rxDataReady.Set();
}

Thank you very much

Upvotes: 1

Views: 233

Answers (2)

eitamal
eitamal

Reputation: 782

To answer the question in the title: No. A blocked thread cannot raise an event. However, if a different thread is responsible for raising the event, it should work as expected.

To illustrate this, here's an example:

internal class Program
{
    private static readonly AutoResetEvent RxDataReady = new AutoResetEvent(false);

    private static event EventHandler ev;

    public static void GetSomeDataFromSerialPort()
    {
        RxDataReady.WaitOne();

        // Process data
    }

    private static void Main()
    {
        ev += ReadDataEventHandler;
        Task.Run(
            async () =>
                {
                    await Task.Delay(5000);
                    ev(null, EventArgs.Empty);
                });
        GetSomeDataFromSerialPort();

        Console.WriteLine("Done.");
        Console.ReadLine();
    }

    private static void ReadDataEventHandler(object sender, EventArgs eventArgs)
    {
        // Prepare data
        RxDataReady.Set();
    }
}

What this code does is simply start a new thread that waits for 5 seconds and then raises an event. If you try running this, you'd see that after 5 seconds "Done." is displayed in the console.

If you were to raise the event on the same thread:

 private static void Main()
    {
        ev += ReadDataEventHandler;
        GetSomeDataFromSerialPort();
        ev(null, EventArgs.Empty);

        Console.WriteLine("Done.");
        Console.ReadLine();
    }

Then the event will never be raised, and execution will never continue beyond RxDataReady.WaitOne().

An alternative to this would be to run GetSomeDataFromSerialPort() on a different thread.

Upvotes: 2

Paul Chen
Paul Chen

Reputation: 1881

The remarks from MSDN SerialPort.DataReceived

The DataReceived event is raised on a secondary thread when data is received from the SerialPort object

So I don't think your code sample will end up deadlocking.

However, the answer to your question in the title:

Can a blocked thread fire events?

No.

Upvotes: 5

Related Questions