最近一个项目中,需要解决上位机与下位机进行串口通讯时,上位机与下位机连接的串口断开检测问题.
以下是我的解决方案:
在下位机与上位机通过串口线连接时,上位机电脑会被随机分配一个串口号,我们只需要在代码中使用一个字符串变量记住该串口号,并定义一个定时器。在一个点击事件,或者主窗体函数中启动定时器,定时检测串口号是否在上位机电脑中存在.
#region 定时器
/// <summary>
/// 串口连接定时器
/// </summary>
private System.Timers.Timer serialLine;
/// <summary>
/// 被监控串口名称
/// </summary>
public string serialname = "";
/// <summary>
/// 定时器开关
/// </summary>
/// <param name="state"></param>
private void StartTimerAsync(bool state) {
try {
if (state) {
if (serialLine == null) {
serialLine = new System.Timers.Timer(10000); // 10秒检测一次
serialLine.Elapsed += new ElapsedEventHandler(DrawTimerFunction);
}
serialLine.Start();
} else {
ClosetimerDraw();
}
} catch(Exception ex) {
MessageBox.Show(ex.ToString());
}
}
/// <summary>
/// 关闭定时器
/// </summary>
public void ClosetimerDraw() {
serialLine.Stop();
serialLine.Dispose();
serialLine = null;
}
/// <summary>
/// 定时器委托方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void DrawTimerFunction(object sender, ElapsedEventArgs e) {
try {
// 获取当前电脑上的所有串口列表
var portNames = SerialPort.GetPortNames();
// serialname 需要被监控是否断开的串口名称
if (Array.IndexOf(portNames, serialname) >= 0) {
serialLine.Start(); // *** 串口没有断开继续监控
} else {
// 可能涉及到ui线程操作
this.Invoke(new Action(() => {
// *** 此处可编写串口断开后的事件
// 断开后关闭定时器
ClosetimerDraw();
}));
}
} catch {
serialLine.Stop();
serialLine.Start();
}
}
#endregion
我是在一个点击事件中去调用
StartTimerAsync(true);开启定时器
StartTimerAsync(false);关闭定时器
第一次编写,如有错误欢迎指正。