【发布时间】:2016-12-28 07:36:26
【问题描述】:
我有一个程序,它依赖于通过串行端口发送的数据。我想监控何时使用SerialPort.ReadLine() 发送数据。我的问题是我使用的复选框在选中时会冻结,因为SerialPort.ReadLine() 方法会阻塞,直到它接收到一些数据。我也尝试过使用ReadTimeout(),但它不起作用;也许是因为我没有正确使用它。
我已在下面发布了此活动的代码。我想要这种方法做的是在选中复选框时监视我的串口,然后在我取消选中该框时停止监视串口。我目前的代码情况是它在选中该框时冻结。感谢所有帮助。
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
if (checkBox1.Checked)
{
checkBox1.Text = "Listening...";
using (SerialPort arduino = new SerialPort())
{
arduino.BaudRate = 9600;
arduino.PortName = comboBox1.Text;
arduino.Open();
string pipe = arduino.ReadLine(); //loop here
if (pipe == "S")
{
//System.Diagnostics.Process.Start("shutdown", "/f /r /t 0");
System.Windows.Forms.Application.Exit();
}
else
{
checkBox1.Text = "Start";
}
}
}
}
【问题讨论】:
-
ReadLine 不用于监控何时发送数据。 SerialPort 类对此有一个事件。您应该提前打开端口并使用 DataReceived 事件。这样做你的 GUI 不会冻结
-
对于 GUI 程序,可以阻塞的操作需要异步完成,以确保 UI 线程保持响应。有关一种方法,请参见标记的副本。请参阅stackoverflow.com/questions/5468039/… 以预测您关于如何从异步完成访问 UI 的下一个问题。请注意,如果您将
async和await与异步 API 一起使用,则无需处理跨线程方面,因为await语句会自动执行此操作。 -
@PeterDuniho 我想知道来自副本的答案是否会帮助 Alexander Stroborg。我不会说这里有必要使用 asynch await 方法。虽然它肯定是一种优雅的方式,但对于初学者来说也不容易掌握。在这种情况下,使用
DataReceived事件就足以解决问题,并且仍然使 GUI 保持响应 -
@Mong:使用
DataReceived也很好,但在 Stack Overflow 上的各种现有问答中也得到了充分的解决。使用它还需要理解和应用处理跨线程访问 UI 组件的技术(根据我上面的其他链接),而await不需要。坦率地说,我认为await对于初学者来说可能更容易学习,因为他们没有不正确的先入之见来干扰他们学习新技术,而新技术是专门设计用于消除大部分处理异步代码通常会让人头疼。
标签: c# winforms checkbox visual-studio-2013 serial-port