C#多线程数据混乱的疑问

Tony_Xian 2017-11-06 11:29:00
同时开三个线程,每个线程一个label控件,用这个控件读取PLC某地址上的数值,线程里面的读数据是用while(true)死循环,里面有if做判断,当读数大于某数值时,用break退出循环,但当同时开两个线程或三个线程时,偶尔会出现一种情况,读数到某一数值时,突然读数变化得很快,然后出现混乱,比如说154,变成1354,或者break无效,读数一直增加,但只开一个线程就没有这两种情况,请教一下各位大神,谢谢!
...全文
677 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
clark_kidd 2017-11-08
  • 打赏
  • 举报
回复
while(true) 是不是太占资源了,读一次后,sleep 100ms,再读比较好。另外,读的线程,是否可以用 lock(plcObject){read();} 来避“读数变化得很快”的问题
正怒月神 2017-11-08
  • 打赏
  • 举报
回复
先拿一部分数据,做一下测试。 线程这方面,需要一点经验猜测。日志也是很有必要的。 不过线程主要问题集中在访问共享资源却没有Lock上。 你可以使用线程安全的集合来存放共享向资源BlockingCollection<T>
XueDEE123 2017-11-08
  • 打赏
  • 举报
回复
你是与一台PLC通讯还是多台,说下思路过程帮你分析
xuzuning 2017-11-06
  • 打赏
  • 举报
回复
婆婆太多,媳妇没法活 你需要精兵简政
Tony_Xian 2017-11-06
  • 打赏
  • 举报
回复
对了,那个ui我直接用的是那个很长的,CheckForIllegalCrossThteadCalls = false
易2017 2017-11-06
  • 打赏
  • 举报
回复
你异步更新界面UI用的invoke还是begininvoke
CRonaldo9399 2017-11-06
  • 打赏
  • 举报
回复
引用 2 楼 boiled_water123 的回复:
对了,那个ui我直接用的是那个很长的,CheckForIllegalCrossThteadCalls = false
private void LableText(Label lable, string str) { if (this.InvokeRequired) { this.BeginInvoke(new MethodInvoker(() => LableText(lable, str))); } else { lable.Text = str; } }
njit_77 2017-11-06
  • 打赏
  • 举报
回复
牵扯到线程问题,最好有日志记录。不然不太好分析问题,找到问题点
xian_wwq 2017-11-06
  • 打赏
  • 举报
回复
CheckForIllegalCrossThteadCalls = false不推荐使用 线程函数内部是怎么处理的? 是否有对公用变量的操作,如果有,那么必须加锁进行同步处理 如果刷新频率秒级,没有必要一个线程一个label
易2017 2017-11-06
  • 打赏
  • 举报
回复
引用 2 楼 boiled_water123 的回复:
对了,那个ui我直接用的是那个很长的,CheckForIllegalCrossThteadCalls = false
不推荐使用,你老老实实用invoke更新试试
吉普赛的歌 2017-11-06
  • 打赏
  • 举报
回复
加下日志, 想办法捕获异常变动时的相关情况
资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 在C#开发中,多线程的使用是提升程序性能和响应能力的重要手段,但如果不正确使用,很容易导致界面假死的问题。界面假死通常是由于在主线程(UI线程)中执行了耗时操作,导致界面无法及时响应用户的交互操作。为了避免这种情况,我们需要正确地使用多线程技术。 首先,对于耗时的操作,应该将其放在单独的线程中执行,而不是在主线程中运行。例如,可以使用Thread类或Task类来创建新的线程来处理这些操作。这样可以避免主线程被阻塞,从而保证界面的流畅性。 其次,在多线程编程中,需要注意线程安全问题。因为多个线程可能会同时访问和修改共享资源,这可能会导致数据不一致或程序崩溃。为了避免这些问题,可以使用锁(如lock语句)或其他同步机制来保护共享资源的访问。 此外,当需要在子线程中更新UI元素时,必须使用Invoke或BeginInvoke方法。因为UI元素只能由主线程更新,直接在子线程中操作UI元素会导致异常。通过Invoke或BeginInvoke方法,可以将更新UI的操作委托给主线程执行。 如果你对C#多线程的使用还有疑问,或者想要了解更多关于解决界面假死问题的方法,可以访问我的博客。由于网络原因,我无法直接解析你提供的链接,可能是链接本身存在问题,或者网络连接不稳定。建议你检查链接的合法性,或者稍后再尝试访问。如果你有其他问题,也可以随时向我提出建议,我会尽力帮助你。

111,118

社区成员

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

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

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