.net 串口通讯(蓝屏,死锁,卡死)

.net 串口通讯(蓝屏,死锁,卡死),第1张

概述.net 串口通讯(蓝屏死锁,卡死)标签: .net通讯textboxcomponentsbyteobject2010-08-06 22:47 1192人阅读 评论(0) 收藏 举报版权声明:本文为博主原创文章,未经博主允许不得转载。   到现在为止,用.net (vs2005)写串口通讯的程序写了好几回了,但到目前为止感觉才把问题解决得较好一些,网上 .net 串口通讯(蓝屏,死锁,卡死) 标签: .net通讯textboxcomponentsbyteobject 2010-08-06 22:47  1192人阅读  评论(0)  收藏  举报

版权声明:本文为博主原创文章,未经博主允许不得转载。

@H_301_29@   到现在为止,用.net (vs2005)写串口通讯的程序写了好几回了,但到目前为止感觉才把问题解决得较好一些,网上也提供了不少方法,我大都用过,发现里面的问题还真不少。其实用过.net中serialPort类的设计人员都会遇到一些问题,但我想真正解决的人却不多。网上提供的方法至少我是没有找到一种行的.我还是先说说会遇到哪些问题吧。

@H_301_29@       我有一个朋友说写的串口程序会使系统蓝屏,我也试用,刚开始写的程序,的确会有大问题,蓝屏了。但引起蓝屏的应该不是程序,这里要究正一下。因为我们在测试的时候都是用虚拟串口的((SUDT SerialNull),我猜引起问题的是这个东西,因为我用单片机的时候是不会出现蓝屏,但发送和接收会出现问题。

@H_301_29@      其次会出现的一个问题是当关闭串口的那个时值程序会卡死,只右击程序才能缓解过来。说来也怪,会出现卡也就算了,但它不是每回都出现,只是偶尔,真是麻烦死了。后来查阅了大量的资料,才发现其实程序中的线程造成死锁引起的,当关闭串口的那一刻,单片机又发送数据,引起一个事件而造成死锁。其实这不是我们的问题,是微软的问题,但愿以后的版本中它能改进,把问题解决。废话说了那么多,还是用代码说话更权威吧。

@H_301_29@以下是我的程序源代码(里面和一些代码你会发现与网上流传的相同,那是因为那些都是大同小异,为了省事我就直接copy了部分。但那些流传的是有错误的,运行会出现大问题)

@H_301_29@ 

@H_301_29@ 

@H_301_29@定义了两个button,它们的name 分别是buttonOpenClose(打开关闭按键)和buttonSend(发送区中的发送按键)都有click事件

@H_301_29@定义了两个TextBox,它们的name 分别是txGet(接收区中的textBox,显示接收的数据)和txSend(发送区的textBox,用于发送数据)

@H_301_29@定义了两个comboBox,它们的name 分别是comboPortname(端口号那个)和comboBaudrate(波特率那个)

@H_301_29@这里的核心代码其实也就那么几句:其中一个是通过委托,然后在接收数据的事件中调用this.Invoke();

@H_301_29@                                                另外一个就是设置两个变量,一个是Listening和Closing,防止死锁

@H_301_29@ 

@H_301_29@ 

@H_301_29@ 

@H_301_29@using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.windows.Forms;
using System.IO.Ports;
//using System.linq;

@H_301_29@using System.Text.RegularExpressions;
namespace 解决串口关闭死锁
{
    public partial class SerialportSampleForm : Form
    {
        private SerialPort comm = new SerialPort();   
        private StringBuilder builder = new StringBuilder();
       //避免在事件处理方法中反复的创建,定义到外面。   
        private long received_count = 0;//接收计数   
        private long send_count = 0;//发送计数   
        private bool Listening = false;
       //是否没有执行完invoke相关 *** 作   
        private bool Closing = false;

      //是否正在关闭串口,执行Application.DoEvents, 并阻止再次invoke   
    

@H_301_29@        public SerialportSampleForm()
        {
            InitializeComponent();
        }
        public static byte[] HexStringToBinary(string hexstring)//十六进制格式转换
        {

@H_301_29@            string[] tmpary = hexstring.Trim().Split(' ');
            byte[] buff = new byte[tmpary.Length];
            for (int i = 0; i < buff.Length; i++)
            {
                buff[i] = Convert.ToByte(tmpary[i],16);//转换
            }
            return buff;
        }
        private voID SerialportSampleForm_Load(object sender,EventArgs e)
        {
            string[] ports = SerialPort.GetPortnames();
            Array.sort(ports);
            comboPortname.Items.AddRange(ports);
            comboPortname.Selectedindex =
            comboPortname.Items.Count > 0 ? 0 : -1;
            comboBaudrate.Selectedindex = comboBaudrate.Items.IndexOf("9600");

@H_301_29@           
            //初始化SerialPort对象
            comm.Newline = "/r/n";
            comm.RtsEnable = true;
            //根据实际情况吧。

@H_301_29@            //添加事件注册
            comm.DataReceived +=comm_DataReceived;

           
        }
        voID comm_DataReceived(object sender,SerialDataReceivedEventArgs e)
       
        {
          
            if (Closing)
            {  
                return; 
            }

       //如果正在关闭,忽略 *** 作,直接返回,尽快的完成串口监听线程的一次循环   
      
            try  
            {   
                Listening = true;
            //设置标记,说明我已经开始处理数据,   一会儿要使用系统UI的。   
             
                int n = comm.BytesToRead;
            //先记录下来,避免某种原因,人为的原因, *** 作几次之间时间长,缓存不一致   
            
                byte[] buf = new byte[n];
             //声明一个临时数组存储当前来的串口数据   
                received_count += n;//增加接收计数   
                comm.Read(buf,n);//读取缓冲数据   
             //   builder.Clear();//清除字符串构造器的内容 
       
                //因为要访问ui资源,所以需要使用invoke方式同步ui。   
                this.Invoke((EventHandler)(delegate  
                {   
                    //判断是否是显示为16禁止   
                    if (checkBoxHexVIEw.Checked)   
                    {   
                        //依次的拼接出16进制字符串   
                        foreach (byte b in buf)   
                        {   
                            builder.Append(b.ToString("X2") + " ");   
                           
                        }   
                    }   
                    else  
                    {   
                        //直接按ASCII规则转换成字符串   
                        builder.Append(EnCoding.ASCII.GetString(buf));   
                    }   
              
                    this.txGet.Text=(builder.ToString()); 
                    //修改接收计数   
                    labelGetCount.Text = "Get:" + received_count.ToString();   
                }));   
            }   
            finally  
            {   
                Listening = false;//我用完了,ui可以关闭串口了。   
            }   
        }

@H_301_29@        private voID buttonOpenClose_Click(object sender,EventArgs e)
        {
            //根据当前串口对象,来判断 *** 作   
            if (comm.IsOpen)   
            {   
                Closing = true;   
                while (Listening) Application.DoEvents();   
                //打开时点击,则关闭串口   
                comm.Close();
                MessageBox.Show(Listening.ToString());
            }   
            else  
            {

@H_301_29@                Closing = false;
                //关闭时点击,则设置好端口,波特率后打开   
                comm.Portname = comboPortname.Text;   
                comm.Baudrate = int.Parse(comboBaudrate.Text);   
                try  
                {   
                    comm.open();   
                }   
                catch(Exception ex)   
                {   
                    //捕获到异常信息,创建一个新的comm对象,之前的不能用了。   
                   
                    comm = new SerialPort();   
                    //现实异常信息给客户。   
                    MessageBox.Show(ex.Message);   
                }   
            }   
            //设置按钮的状态   
            buttonOpenClose.Text = comm.IsOpen ? "Close" : "Open";
            buttonSend.Enabled = comm.IsOpen;
        }

@H_301_29@        private voID buttonSend_Click(object sender,EventArgs e)
        {
            //定义一个变量,记录发送了几个字节   
            int n = 0;   
            //16进制发送   
            if (checkBoxHexSend.Checked)   
            {   
               

@H_301_29@                byte[] send = HexStringToBinary(txSend.Text.Trim());

@H_301_29@              comm.Write(send,send.Length);
          
    
                //记录发送的字节数   
              n++;
            }   
            else//ascii编码直接发送   
            {   
              
                    comm.Write(txSend.Text);   
                    n = txSend.Text.Length;   
                 
            }   
            send_count += n;//累加发送字节数   
            labelSendCount.Text = "Send:" + send_count.ToString();
           //更新界面  

@H_301_29@        }

@H_301_29@     
    }
}

@H_301_29@ 

@H_301_29@ 

@H_301_29@以下是界面设计的代码:

@H_301_29@ 

@H_301_29@ 

@H_301_29@namespace 解决串口关闭死锁
{
    partial class SerialportSampleForm
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.IContainer components = null;

@H_301_29@        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
        protected overrIDe voID dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.dispose();
            }
            base.dispose(disposing);
        }

@H_301_29@        #region windows 窗体设计器生成的代码

@H_301_29@        /// <summary>
        /// 设计器支持所需的方法 - 不要
        /// 使用代码编辑器修改此方法的内容。
        /// </summary>
        private voID InitializeComponent()
        {
            this.comboPortname = new System.windows.Forms.ComboBox();
            this.comboBaudrate = new System.windows.Forms.ComboBox();
            this.checkBoxHexVIEw = new System.windows.Forms.CheckBox();
            this.labelGetCount = new System.windows.Forms.Label();
            this.buttonOpenClose = new System.windows.Forms.button();
            this.buttonSend = new System.windows.Forms.button();
            this.labelSendCount = new System.windows.Forms.Label();
            this.checkBoxHexSend = new System.windows.Forms.CheckBox();
            this.txSend = new System.windows.Forms.TextBox();
            this.txGet = new System.windows.Forms.TextBox();
            this.label1 = new System.windows.Forms.Label();
            this.label2 = new System.windows.Forms.Label();
            this.label3 = new System.windows.Forms.Label();
            this.label4 = new System.windows.Forms.Label();
            this.groupBox1 = new System.windows.Forms.GroupBox();
            this.groupBox2 = new System.windows.Forms.GroupBox();
            this.groupBox3 = new System.windows.Forms.GroupBox();
            this.groupBox4 = new System.windows.Forms.GroupBox();
            this.groupBox1.SuspendLayout();
            this.groupBox2.SuspendLayout();
            this.groupBox3.SuspendLayout();
            this.groupBox4.SuspendLayout();
            this.SuspendLayout();
            // 
            // comboPortname
            // 
            this.comboPortname.FormattingEnabled = true;
            this.comboPortname.Location = new System.Drawing.Point(60,20);
            this.comboPortname.name = "comboPortname";
            this.comboPortname.Size = new System.Drawing.Size(121,20);
            this.comboPortname.TabIndex = 0;
            // 
            // comboBaudrate
            // 
            this.comboBaudrate.FormattingEnabled = true;
            this.comboBaudrate.Items.AddRange(new object[] {
            "9600"});
            this.comboBaudrate.Location = new System.Drawing.Point(60,56);
            this.comboBaudrate.name = "comboBaudrate";
            this.comboBaudrate.Size = new System.Drawing.Size(121,20);
            this.comboBaudrate.TabIndex = 1;
            // 
            // checkBoxHexVIEw
            // 
            this.checkBoxHexVIEw.autoSize = true;
            this.checkBoxHexVIEw.Checked = true;
            this.checkBoxHexVIEw.CheckState = System.windows.Forms.CheckState.Checked;
            this.checkBoxHexVIEw.Location = new System.Drawing.Point(80,29);
            this.checkBoxHexVIEw.name = "checkBoxHexVIEw";
            this.checkBoxHexVIEw.Size = new System.Drawing.Size(96,16);
            this.checkBoxHexVIEw.TabIndex = 2;
            this.checkBoxHexVIEw.Text = "十六进制显示";
            this.checkBoxHexVIEw.UseVisualStyleBackcolor = true;
            // 
            // labelGetCount
            // 
            this.labelGetCount.autoSize = true;
            this.labelGetCount.Location = new System.Drawing.Point(33,31);
            this.labelGetCount.name = "labelGetCount";
            this.labelGetCount.Size = new System.Drawing.Size(29,12);
            this.labelGetCount.TabIndex = 4;
            this.labelGetCount.Text = "接收";
            // 
            // buttonOpenClose
            // 
            this.buttonOpenClose.Location = new System.Drawing.Point(258,319);
            this.buttonOpenClose.name = "buttonOpenClose";
            this.buttonOpenClose.Size = new System.Drawing.Size(75,37);
            this.buttonOpenClose.TabIndex = 5;
            this.buttonOpenClose.Text = "打开";
            this.buttonOpenClose.UseVisualStyleBackcolor = true;
            this.buttonOpenClose.Click += new System.EventHandler(this.buttonOpenClose_Click);
            // 
            // buttonSend
            // 
            this.buttonSend.Location = new System.Drawing.Point(83,75);
            this.buttonSend.name = "buttonSend";
            this.buttonSend.Size = new System.Drawing.Size(75,23);
            this.buttonSend.TabIndex = 6;
            this.buttonSend.Text = "发送";
            this.buttonSend.UseVisualStyleBackcolor = true;
            this.buttonSend.Click += new System.EventHandler(this.buttonSend_Click);
            // 
            // labelSendCount
            // 
            this.labelSendCount.autoSize = true;
            this.labelSendCount.Location = new System.Drawing.Point(33,64);
            this.labelSendCount.name = "labelSendCount";
            this.labelSendCount.Size = new System.Drawing.Size(29,12);
            this.labelSendCount.TabIndex = 9;
            this.labelSendCount.Text = "发送";
            // 
            // checkBoxHexSend
            // 
            this.checkBoxHexSend.autoSize = true;
            this.checkBoxHexSend.Checked = true;
            this.checkBoxHexSend.CheckState = System.windows.Forms.CheckState.Checked;
            this.checkBoxHexSend.Location = new System.Drawing.Point(82,22);
            this.checkBoxHexSend.name = "checkBoxHexSend";
            this.checkBoxHexSend.Size = new System.Drawing.Size(72,16);
            this.checkBoxHexSend.TabIndex = 10;
            this.checkBoxHexSend.Text = "十六进制";
            this.checkBoxHexSend.UseVisualStyleBackcolor = true;
            // 
            // txSend
            // 
            this.txSend.Location = new System.Drawing.Point(82,46);
            this.txSend.name = "txSend";
            this.txSend.Size = new System.Drawing.Size(82,21);
            this.txSend.TabIndex = 12;
            // 
            // txGet
            // 
            this.txGet.Location = new System.Drawing.Point(82,52);
            this.txGet.Multiline = true;
            this.txGet.name = "txGet";
            this.txGet.Size = new System.Drawing.Size(112,21);
            this.txGet.TabIndex = 13;
            // 
            // label1
            // 
            this.label1.autoSize = true;
            this.label1.Location = new System.Drawing.Point(17,52);
            this.label1.name = "label1";
            this.label1.Size = new System.Drawing.Size(65,12);
            this.label1.TabIndex = 14;
            this.label1.Text = "发送数据:";
            // 
            // label2
            // 
            this.label2.autoSize = true;
            this.label2.Location = new System.Drawing.Point(24,58);
            this.label2.name = "label2";
            this.label2.Size = new System.Drawing.Size(65,12);
            this.label2.TabIndex = 15;
            this.label2.Text = "接收数据:";
            // 
            // label3
            // 
            this.label3.autoSize = true;
            this.label3.Location = new System.Drawing.Point(6,23);
            this.label3.name = "label3";
            this.label3.Size = new System.Drawing.Size(29,12);
            this.label3.TabIndex = 16;
            this.label3.Text = "端口";
            // 
            // label4
            // 
            this.label4.autoSize = true;
            this.label4.Location = new System.Drawing.Point(6,56);
            this.label4.name = "label4";
            this.label4.Size = new System.Drawing.Size(41,12);
            this.label4.TabIndex = 17;
            this.label4.Text = "波特率";
            // 
            // groupBox1
            // 
            this.groupBox1.Controls.Add(this.txSend);
            this.groupBox1.Controls.Add(this.label1);
            this.groupBox1.Controls.Add(this.buttonSend);
            this.groupBox1.Controls.Add(this.checkBoxHexSend);
            this.groupBox1.Location = new System.Drawing.Point(316,170);
            this.groupBox1.name = "groupBox1";
            this.groupBox1.Size = new System.Drawing.Size(223,114);
            this.groupBox1.TabIndex = 20;
            this.groupBox1.TabStop = false;
            this.groupBox1.Text = "发送区";
            // 
            // groupBox2
            // 
            this.groupBox2.Controls.Add(this.txGet);
            this.groupBox2.Controls.Add(this.label2);
            this.groupBox2.Controls.Add(this.checkBoxHexVIEw);
            this.groupBox2.Location = new System.Drawing.Point(50,170);
            this.groupBox2.name = "groupBox2";
            this.groupBox2.Size = new System.Drawing.Size(223,114);
            this.groupBox2.TabIndex = 21;
            this.groupBox2.TabStop = false;
            this.groupBox2.Text = "接收区";
            // 
            // groupBox3
            // 
            this.groupBox3.Controls.Add(this.labelGetCount);
            this.groupBox3.Controls.Add(this.labelSendCount);
            this.groupBox3.Location = new System.Drawing.Point(316,28);
            this.groupBox3.name = "groupBox3";
            this.groupBox3.Size = new System.Drawing.Size(200,99);
            this.groupBox3.TabIndex = 22;
            this.groupBox3.TabStop = false;
            this.groupBox3.Text = "统计区";
            // 
            // groupBox4
            // 
            this.groupBox4.Controls.Add(this.comboPortname);
            this.groupBox4.Controls.Add(this.comboBaudrate);
            this.groupBox4.Controls.Add(this.label3);
            this.groupBox4.Controls.Add(this.label4);
            this.groupBox4.Location = new System.Drawing.Point(50,28);
            this.groupBox4.name = "groupBox4";
            this.groupBox4.Size = new System.Drawing.Size(200,99);
            this.groupBox4.TabIndex = 23;
            this.groupBox4.TabStop = false;
            this.groupBox4.Text = "设置区";
            // 
            // SerialportSampleForm
            // 
            this.autoScaleDimensions = new System.Drawing.Sizef(6F,12F);
            this.autoScaleMode = System.windows.Forms.autoScaleMode.@R_404_6837@;
            this.ClIEntSize = new System.Drawing.Size(571,453);
            this.Controls.Add(this.groupBox4);
            this.Controls.Add(this.groupBox3);
            this.Controls.Add(this.groupBox2);
            this.Controls.Add(this.groupBox1);
            this.Controls.Add(this.buttonOpenClose);
            this.name = "SerialportSampleForm";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.SerialportSampleForm_Load);
            this.groupBox1.ResumeLayout(false);
            this.groupBox1.Performlayout();
            this.groupBox2.ResumeLayout(false);
            this.groupBox2.Performlayout();
            this.groupBox3.ResumeLayout(false);
            this.groupBox3.Performlayout();
            this.groupBox4.ResumeLayout(false);
            this.groupBox4.Performlayout();
            this.ResumeLayout(false);

@H_301_29@        }

@H_301_29@        #endregion

@H_301_29@        private System.windows.Forms.ComboBox comboPortname;
        private System.windows.Forms.ComboBox comboBaudrate;
        private System.windows.Forms.CheckBox checkBoxHexVIEw;
        private System.windows.Forms.Label labelGetCount;
        private System.windows.Forms.button buttonOpenClose;
        private System.windows.Forms.button buttonSend;
        private System.windows.Forms.Label labelSendCount;
        private System.windows.Forms.CheckBox checkBoxHexSend;
        private System.windows.Forms.TextBox txSend;
        private System.windows.Forms.TextBox txGet;
        private System.windows.Forms.Label label1;
        private System.windows.Forms.Label label2;
        private System.windows.Forms.Label label3;
        private System.windows.Forms.Label label4;
        private System.windows.Forms.GroupBox groupBox1;
        private System.windows.Forms.GroupBox groupBox2;
        private System.windows.Forms.GroupBox groupBox3;
        private System.windows.Forms.GroupBox groupBox4;
    }
}

@H_301_29@ 

@H_301_29@ 

@H_301_29@如果你们发现运行有错误,谢谢留言,会及时更改。谢谢,另外,源代码的工程文件我会上传到资源共享里~~~~~~

总结

以上是内存溢出为你收集整理的.net 串口通讯(蓝屏,死锁,卡死)全部内容,希望文章能够帮你解决.net 串口通讯(蓝屏,死锁,卡死)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1213026.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存