解决SerialPort的死锁

本文主要探讨在使用C# SerialPort时遇到的死锁问题,特别是在关闭串口时导致页面卡死的情况。文章分析了SerialPort类关闭操作引发的死锁原因,并提出通过BeginInvoke异步更新避免同步线程更新引发的死锁。同时,介绍了ISynchronizeInvoke接口在多线程环境下处理消息的方法,以及BeginInvoke和Invoke的区别。
摘要由CSDN通过智能技术生成

今天在用SerialPort时候遇到咋关闭串口时候出现页面卡住不动的情况,通过查询一些资料终于找到解决方案了。第一次写这种技术贴,组织比较混乱,请见谅

在兔子党逍遥的文章http://blog.csdn.net/wuyazhe/article/details/5606276 中有分析道在SerialPort串口类关闭串口时候会陷入死锁,也提供一种用Application.DoEvent()解决;

但是此处的Application是System.Windows.Forms中的方法,而我在Bll层....这不是个好办法

通过查询Invoke,知晓Invoke是同步线程更新,在循环执行DataReceived中的线程时,插入串口的Close事件,因为Invoke的等待状态没有返回,导致死锁。

于是通过BeginInvoke异步执行更新,在While循环(见下面代码)中使用Lock,控制更新内容的顺序。

这里有关于Invoke和BeginInvoke的区别比较http://www.cnblogs.com/Rustle/articles/11301.aspx

这里只是部分主要代码

BLL层

private SerialPort sp = new SerialPort(){PortName = "COM3",DataBits = 8,StopBits = StopBits.One,Parity = Parity.None};
private object spObj = new object();

public void OpenPort(ProcessDelegate processModel)
{
    dealThread = new Thread(new ThreadStart(StartPortMethod));
    _interalPd = processModel;
    dealThread.Start();
}

void StartPortMethod()
{
    try
    {
        sp.Open();
        sp.DataReceived += sp_DataReceived;
    }
}
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    int len = sp.BytesToRead; //串口传过来的数据位数
    var bBuff = new byte[len];
    sp.Read(bBuff, 0, len); //把数据放进缓存

    while (flagIndex < bBuff.Length)
    {
        //TODO:从缓存区获取一个数据包
	//解析数据包
        _dRModel = _rTrans.TransReceivedData(perBytePackage.ToArray());
        //利用委托将model数据返回给UI
        _interalPd(_dRModel);
        }
    }
}

public void ClosePort()
{
    try
    {
        if (sp.IsOpen)
        {
            dealThread.Abort();
            sp.DataReceived -= sp_DataReceived;
            sp.Close();
        }
    }
    catch (Exception)
    {
        throw;
    }
}

UI层

        /// <summary>
        /// 接收从bll返回的数据并通过Invoke更新
        /// </summary>
        /// <param name="rdmodel"></param>
        void UpdateReceivedData(ReceivedDataModel rdmodel)
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值