庄低调Thread和task学习笔记

C#winform.timer_tick因主线程线程而丢失的问题及解决方案

一、不断读取位置失效

  1. 故事背景
    在控制运动轴时,需要用到特殊的运动算法,每一次控制需要移动一小段的固定的距离,因此在算法中间用到了Thread.sleep保证马达运动到位再开始下一步的运动(虽然可以提高运动速度,但是速度高会丢步)。而程序自开始运行就在不断读取轴的位置,用到的是winform.timer。问题来了,当轴在单独的点位运动或者单独的连续运动时,timer事件还是可以正常读取,但是!在算法执行过程中,timer就不动了!查了许多,了解到了其他的内容写了另一篇关于winform控件、不同线程调用控件和异步编程的问题,戳笔记
  2. 解决方法
    当找出解决方法时,发现自己很蠢。问题的根本已经在上面说到了,罪魁祸首就是Thread.sleep。解决方法就是将算法方法前加async,Thread.sleep改成 await Task.Delay。完结,撒花?再多写一点。
    不能去掉await!Thread.sleep适用于你的程序都是串行的状况,就是画成流程图都是竖着看的。像本人这次遇到问题的程序是有两个并行感觉,实际还是串行执行,只是因为方法之间切换时间短所以像并行。打个比方就是一个老师喂3个小孩吃饭,不管每个碗有多少饭,编号1、2、3,按照顺序每人每次喂一口。等到有小孩吃完时,还有人在吃,这样就特别像并行完成的亚子。希望我以后不会忘记。
    说回Task.Delay它不加await的话就是个摆设,CPU有执行,但是只是把它丢给新线程去执行,丢完不管结果就接着执行Task.Delay的下一句。加了await呢,就会真的等一段时间后再执行Task.Delay的下一条语句。但是,跟Thread.Sleep不同的是,Thread.sleep会阻塞,不仅自己的线程没法接着跑,别人的也不能跑,拿上面老师来说就是,把老师独占了,还把嘴巴闭上了。Task.Delay(加await)可以边等边计时,再计时还没结束时,先把其他的事情做了,即使结束再接着继续task下一句。拿上面喂饭例子讲,就是不管你嘴巴闭上多久,我都能抽身去喂别人,等你时间到了就恢复之前一人一口。因此,加了await还是串行,不行并行。(并行是老师手脚并用,同时喂)。
    完结,撒花·

你可能感兴趣的:(WindowsForms,学习笔记,c#)