Reputation: 41
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
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
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