C#开发上位机监听器程序闪退现象

qq_39033657 2017-11-16 11:58:34
在监听数据的时候,读取串口接收的数据进行解析,解析出来的数据实时在文本框中显示,接收的数据量很多也很快,程序工作时间长了会出现闪退现象,这是怎么回事?
...全文
659 7 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_39033657 2017-11-25
  • 打赏
  • 举报
回复
谢谢各位的回复
Antony_WU_SZ 2017-11-20
  • 打赏
  • 举报
回复
串口过时了,个人经验,搞成网口吧,走TCP通讯就没有这么多问题了。
圣殿骑士18 2017-11-18
  • 打赏
  • 举报
回复
关键代码并不完整。比如,刷新的机制是什么?读取的数据是通过什么逻辑显示到界面上的? 而且跨线程逻辑很啰嗦,感觉应该没实现跨线程的机制,所谓BeginInvoke没有真正起作用。 跨UI线程很简单,不需要定时刷新,不需要DoEvents。BeginInvoke足够。
/// <summary>
        /// 读取线程
        /// </summary>
        /// <param name="list"></param>
        void reader_TagsReport(List<TagInfo> list)
        {
            if (list.Count == 0) return;

            bool tagNew = false;
            DateTime? newReadTime = null;
            list.ForEach((x) =>
            {
                var tag = listTag.Find(c => c.Epc == x.Epc);
                if (tag == null)
                {
                    var tagnew = new TagInfo()
                    {
                        Epc = x.Epc,
                        ReadCount = 1,
                        ReadTime = DateTime.Now,
                        ReaderId = x.ReaderId,
                        AntennaId = x.AntennaId
                    };
                    lock (listTag)
                    {
                        listTag.Add(tagnew);
                        newReadTime = DateTime.Now;
                        tagNew = true;
                    }
                }
                else
                {
                    lock (listTag)
                    {
                        tag.ReadCount++;
                        tag.ReadTime = DateTime.Now;
                        tag.ReaderId = x.ReaderId;
                        tag.AntennaId = x.AntennaId;
                    }
                }
            });

            //刷新UI
            if (tagNew) //读取到新标签
            {
                this.BeginInvoke(new Action<bool, DateTime?>(BindData), true, newReadTime);
            }
            else //旧标签的重复读取
            {
                //进行时间间隔控制:如果刷新频率太高,即使跨线程调用也会把UI线程卡死的
                DateTime dtNow = DateTime.Now;
                if (lastRead == null || (dtNow - lastRead).TotalMilliseconds > 100)
                {
                    this.BeginInvoke(new Action<bool, DateTime?>(BindData), false, null);
                    lastRead = dtNow;
                }
            }
        }

        /// <summary>
        /// UI线程刷新
        /// </summary>
        /// <param name="readTime"></param>
        /// <param name="isNew"></param>
        private void BindData(bool isNew, DateTime? readTime)
        {
            var bindingList = this.gridEpcs.DataSource as BindingList<TagInfo>;
            bindingList.ResetBindings();

            if (isNew) lbCount.Text = listTag.Count.ToString();
            if (readTime.HasValue)
            {
                TimeSpan ts = readTime.Value - readStart;
                lbTimeCount.Text = ts.Seconds.ToString() + "s" + ts.Milliseconds.ToString();
            }
        }
qq_39033657 2017-11-18
  • 打赏
  • 举报
回复
第一次开发上位机,自己还是个菜鸟,感谢各位大神的回复。 下面是串口接收函数和数据实时刷新的函数,望哪位大神指导,谢谢。

  int received_count;
        //接收的buffer
        byte[] serial_buf = new byte[10240000];
        bool is_rev = false;

        FrameParsor parsor;
        /// <summary>
        /// 传输数据逻辑修改,需要修改的地方为bytes转str的那一步
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mycom_DataReceived(object sender, EventArgs e)  //接收串口数据并分析
        {
            if (closing)
                return;
            try
            {
                is_rev = true;
                int n = mycom.BytesToRead;
               
                if (n < 1)
                {
                    //***接收完成状态指示。
                    is_rev = false;
                    return;
                }
                //读数据,
               if( n > 10240000)
                {
                    n = 10240000;
                }

                byte[] data = new byte[n];
              
                mycom.Read(serial_buf, 0, n);
                //使用FrameParsor转换数据格式
               
                Array.Copy(serial_buf, 0, data, 0 ,n);
                parsor.AddFrame(data);
                Thread.Sleep(10);
            }
            catch (Exception ex)
            {
               //
 Log.WriteLog(ex);
                throw ex;
            }
            finally
            {
                is_rev = false;
            }

        }

        /// <summary>
        /// 定时刷新com_txt组件
        /// </summary>
        /// <param name="obj"></param>
        //
        void flushComTxt(object obj)
        {
            if(com_txt_add.Length() <= 0)
            {
                return;
            }
            com_txt.BeginInvoke(new EventHandler(delegate
            {
                //***正在处理字符串。
                DoingStr = true;
                if (true == checkBox1.Checked)
                {
                    if (com_txt.Text.Length > 131072)
                    {
                        com_txt.Text = string.Empty;
                    }

                    com_txt.AppendText(com_txt_add.Empty());
                    com_txt_add.Empty();
                    //将控件的内容滚动到当前位置。
                    com_txt.ScrollToCaret();
                }
                //***完成处理字符串。
                DoingStr = false;
            }
                ));
            while (DoingStr)
            {
                //处理其它系统消息。
                Application.DoEvents();


            }
        }
sdfgrtyu 2017-11-16
  • 打赏
  • 举报
回复
上代码啊上代码
圣殿骑士18 2017-11-16
  • 打赏
  • 举报
回复
看内存有没有释放?如果内存使用一直增加没有释放,程序迟早要崩溃。
xian_wwq 2017-11-16
  • 打赏
  • 举报
回复
闪退是表象,原因靠猜是不行的 先捕获下异常吧

   Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
   AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

111,092

社区成员

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

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

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