我有一个程序,它产生一个控制串行通信的线程。当它等待串口上的响应时,我用AutoResetEvent阻塞线程。
收到数据时,该线程是否无法执行该事件,因为它被阻止了?
为了说明这一点,我在下面有一个简单版本的代码。这段代码是否会导致死锁,或者事件是否会在被阻塞的线程中运行,最终会自行唤醒?
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();
}
非常感谢
答案 0 :(得分:4)
来自MSDN SerialPort.DataReceived
的评论从SerialPort对象接收数据时,在辅助线程上引发DataReceived事件
所以我认为您的代码示例不会导致死锁。
但是,标题中的问题答案为:
被阻止的线程可以触发事件吗?
没有
答案 1 :(得分:1)
回答标题中的问题:否。被阻止的线程无法引发事件。 但是,如果另一个线程负责引发事件,它应该按预期工作。
为了说明这一点,这是一个例子:
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();
}
}
这段代码的作用就是启动一个等待5秒然后引发事件的新线程。 如果你尝试运行它,你会在5秒后看到“完成”。显示在控制台中。
如果您要在同一个帖子上举起活动:
private static void Main()
{
ev += ReadDataEventHandler;
GetSomeDataFromSerialPort();
ev(null, EventArgs.Empty);
Console.WriteLine("Done.");
Console.ReadLine();
}
然后永远不会引发事件,执行将永远不会超过RxDataReady.WaitOne()
。
另一种方法是在另一个线程上运行GetSomeDataFromSerialPort()
。