C#学习--项目实战之串口通信工具二

写在前面

上一篇文章讲解了串口通信的基本实现,这张讲一下我在做这个基于串口通信项目时遇到的问题,因为是一个比较针对性的项目,所以这篇文章可能不适合大多数人。

关于多线程处理接受数据

串口通信在实际的应用当中,常常会遇到这样的情况,接受到的数据接受并处理,然后在UI上做相应的显示,这个时候上位机程序运行的时间会大大影响串口通信的速度,所以这里要用多线程,接受工作线程接受到数据之后只做存储,后续操作交给其他工作线程来完成。上代码

		public void StartSaveDataBW()
        {
            try
            {
                timeNow = DateTime.Now;
                saveDatas_BW = new BackgroundWorker();
                saveDatas_BW.DoWork += SaveDatas_BW_DoWork;
                saveDatas_BW.ProgressChanged += SaveDatas_BW_ProgressChanged;
                saveDatas_BW.WorkerReportsProgress = true;
                saveDatas_BW.RunWorkerAsync();
            }
            catch (Exception)
            {
                MessageBox.Show("多线程启动失败");
            }
        }

        private void SaveDatas_BW_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            if (e.ProgressPercentage == -10)
            {
                NotificationMessage msg = new NotificationMessage(this, Notifications.UpdateSaveProgress);
                Messenger.Default.Send<NotificationMessage>(msg);
            }
            else if (e.ProgressPercentage == -1)
            {
                MessageBox.Show("数据保存失败");
            }
        }

        private void SaveDatas_BW_DoWork(object sender, DoWorkEventArgs e)
        {
            while (IsStartSaveDataModel)
            {
                try
                {
                    operation()//处理操作
                    saveDatas_BW.ReportProgress(-10);
                }
                catch (Exception ex)
                {
                    ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                    log.Info(ex.Message);
                    saveDatas_BW.ReportProgress(-1);
                }
            }
        }

这里省略了接收数据的代码,接受数据代码可以参考上一篇文章,主要功能是接受并存储。

关于多线程更新UI

很多同学会说,我不想用多线程,我想直接访问主线程变动UI层,但会报错,这可怎么办啊。这里谈我的一些理解啊,注册路由事件其实就是创建一个隐藏的工作线程,满足触发条件就会开启这个线程,其实在你不经意之间已经熟练掌握多线程了,神不神奇!意不意外!那么的你的问题就找到原因了,因为接受数据也是注册的路由世界,所以你在接收数据里的操作都是在工作线程中完成的,你想要从工作线程直接访问主线程,就必须用到Dispatcher了,上代码

		private void Receive(NotificationMessage msg)
        {
            if (msg.Notification == Notifications.UpdateTextBoxMessage && msg.Sender == mainViewModel)
            {
                System.Threading.Thread.Sleep(100);
                this.Dispatcher.Invoke(new System.Action(() => {
                    test();//变动UI
                }));
            }
        }

其实原理我也不太懂,意思就是,这部分代码帮你从工作线程切换回了主线程,这样更新UI就不成问题了。

关于接收数据的储存和处理

对于储存数据每个人应该都有自己的习惯和心得把,这里说一些我的心得和理解。
对于类似串口通信的情况,我会用队列来储存数据 “(Queue< T >)”,首先它是一个FIFO的集合,先进先出,便于数据的读取和维护,其次它的性能在Add和Remove上都是O(1) (这个同学们可以百度关键词“集合性能”),这里知道队列的Add和Remove操作都非常快就行了。这两个主要原因让我选择用队列来做为存储数据的一个集合。

public Queue<List<double>[]> saveAnalogChannelsDataQ = new Queue<List<double>[]>();
saveAnalogChannelsDataQ.Enqueue(Item1);
Item2 = saveAnalogChannelsDataQ.Dequeue();

关于数据的处理本文不做过多的讲解,下一篇文章里将会详细讲解:我理解的数据储存原理。

写在结尾

结尾给大家说个经历吧,之前有一篇文章我说过,培训班挺好的,现在我收回这句话,培训班也是因人而异的,我前几天就碰到这么一个朋友(贴吧认识的),他发了一个问题贴,我就评论了两句,然后他就加了我好友,问了我几个问题,但我没有立刻回答他(拒绝伸手党)。我跟他聊了几句,他是看培训视频学的,看完一部分,视频里的老师运行成功了,然后他跟着把代码打出来,但是呢,他却运行不成功,本着授人以鱼不如授人以渔的心态,我说:朋友,你要真想学就放下视频,买基础的书先看看,了解一下这个语言。我以为他会欣然接受,转折来了,他来了一句,书上的东西太基础了。。。。所以我觉得现在是个阿猫阿狗都拍个教学视频给别人看,真的误认子弟,一步一步的打代码,但凡有手会26个字母的,谁做不出来?这就给了很多新人一个错觉,看着自己写的代码洋洋得意,编程也就这样嘛,我这不就完成了么,其实呢,但凡里面错一个大小写,他都不知道问题出在哪里,VS工具也不会用,报错也不会看,所以我在这里再次声明,我的文章不适合新手看,我只是谈论一些自己的理解,如果有同学觉得我说的有问题,欢迎来讨论。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值