如何实现安全的关闭串口消息?

bcc222 2012-05-04 11:48:25

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO.Ports;

namespace com测试
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void textBox1_TextChanged(object sender, EventArgs e)
{

}

Mutex m_Mutex = null;//锁

private void Form1_Load(object sender, EventArgs e)
{
serialPort1 = new SerialPort("com1", 2400, Parity.Even, 7, StopBits.One);
m_Mutex = new Mutex();
flag = false;
}

delegate void setTextCallback(string msg);

bool flag;

SerialPort serialPort1;
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{

if (flag==true)
{
return;
}
m_Mutex.WaitOne();//这个地方加一个互斥

if (serialPort1.IsOpen)
{
setTextCallback d = new setTextCallback(addText);
string temp = serialPort1.ReadTo("49").ToString();
this.BeginInvoke(d, new object[] { temp });
}
m_Mutex.ReleaseMutex();


}
void addText(string msg)
{
richTextBox1.AppendText(msg);

}

private void btnOpen_Click(object sender, EventArgs e)
{
this.serialPort1.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);
serialPort1.Open();
this.btnOpen.Enabled = false;
this.btnClose.Enabled = true;
this.flag = false;
}

private void btnClose_Click(object sender, EventArgs e)
{
m_Mutex.WaitOne();
{
this.serialPort1.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);//先关掉对应的事件
}
serialPort1.Close();//然后关掉程序
flag = true;
m_Mutex.ReleaseMutex();

this.btnOpen.Enabled = true;
this.btnClose.Enabled = false;

}
}
}

}

最近做了一个小的获取com口数据的程序,我想把com口安全的进行关闭,如果要是直接关闭的话,则com事件会报错,所以我就对进程加上了一个互斥!现在的问题是,如果你按关闭和开启过快的话,或者多次按动,则会导致程序死掉,没有反应!各位有没有什么好的方法?

串口或者其他程序触发的事件可不可以看做是一个小的线程?

另外,我要是删除掉事件的话,原来的异步事件是直接被over掉还是等执行完最后一个再进行处理?
...全文
161 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
bcc222 2012-05-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]
btnClose_Click中的互斥,不能保证接收事件不再执行,如果已经进入了接收事件的WaitOne,那么即使你 -= 了,当释放互斥后,一样会继续执行接收事件后面的代码
[/Quote]

也就是说,我在点了关闭以后,很有可能程序是在执行到了waitone里面。
我把程序稍微调整了一下:

private void btnClose_Click(object sender, EventArgs e)
{
flag = true;//先置给事件一个关闭信号

this.serialPort1.DataReceived -= new System.IO.Ports.SerialDataReceivedEventHandler(this.serialPort1_DataReceived);//关掉对应的事件
Thread.Sleep(100);//等待几毫秒
m_Mutex.WaitOne();
serialPort1.Close();//然后关掉端口
m_Mutex.ReleaseMutex();
}

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)//数据接收部分
{

if (flag==true)//这个地方让事件尽快退出去。
{
return;
}
m_Mutex.WaitOne();//这个地方加一个互斥

if (serialPort1.IsOpen)
{
setTextCallback d = new setTextCallback(addText);
string temp = serialPort1.ReadTo("49").ToString();
this.BeginInvoke(d, new object[] { temp });
}
m_Mutex.ReleaseMutex();
}



上面修改过的测试了一下,暂时没有发现问题,但是在逻辑的可能性上,这个地方:

Thread.Sleep(100);//等待几毫秒,这个地方的时间是没有办法进行确定的!!程序运行的时候也有可能出错。

大家还有什么好的意见么?


bdmh 2012-05-04
  • 打赏
  • 举报
回复
btnClose_Click中的互斥,不能保证接收事件不再执行,如果已经进入了接收事件的WaitOne,那么即使你 -= 了,当释放互斥后,一样会继续执行接收事件后面的代码
bcc222 2012-05-04
  • 打赏
  • 举报
回复
自己搞定了!有看到的可以站短
bcc222 2012-05-04
  • 打赏
  • 举报
回复
沉的好快,自己顶先!

111,126

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧