Application.DoEvents();多次调用会有什么隐患,望有经验的朋友分享下!

来个电饭锅 2015-12-10 11:37:05
上位机通过并口模拟IIC和芯片通信,由于部分地方需要较长延时,所以很多地方都用到了Thread.Sleep(),导致主界面出现假死的情况。最后把Sleep函数都换成了Delay
public static void Delay(uint ms)
{
uint start = GetTickCount();
while (GetTickCount() - start < ms)
{
Application.DoEvents();
}
}
这样的确没有出现假死情况。

但是网上有些人说 Application.DoEvents()调用多次后会存在隐患。希望有经验的大神给点指点,用过的朋友分享下经验,看是否到底真会出现异常吗,出现怎样的异常?

还有别人数用Timer可以替代Sleep,希望有实例的朋友可以贴下!!
...全文
1558 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
泡泡龙 2015-12-12
  • 打赏
  • 举报
回复
看楼主应该是只懂单线程编程逻辑,应该考虑使用多线程或者事件驱动机制
来个电饭锅 2015-12-11
  • 打赏
  • 举报
回复
引用 3 楼 sp1234 的回复:
把设计中各种事件循环发生,代码上写成许多个死循环,这是没有学过应用程序设计的表现(可能只是从一些数学相关的课程中学了一些简单的函数编程)。一定要从设计思路上学会事件驱动的设计方法,而不是纠结于编程语句。
Timer我可以用在UI线程中,从而不用Thread.Sleep。 如果我在其他的类中用到了Thread.Sleep(),UI线程中调用了该类(重新开了一个线程)。我需要替换掉Thread.Sleep()吗?如果替换用什么替换呢?麻烦指点!谢谢
  • 打赏
  • 举报
回复
把设计中各种事件循环发生,代码上写成许多个死循环,这是没有学过应用程序设计的表现(可能只是从一些数学相关的课程中学了一些简单的函数编程)。一定要从设计思路上学会事件驱动的设计方法,而不是纠结于编程语句。
  • 打赏
  • 举报
回复
另外,在应用程序设计中搞“死循环”这是很令人不忍看、不忍“闻”的设计方式。如果你认为主线程经常要重复干一件(逻辑的)事儿,就必须写一个死循环,那么我只能说我们是绝对不用这样的程序员的。 在设计上,除非万不得已实在活不下去了,否则不允许随便写“死循环、阻塞”的代码。 写死循环,是因为有些人只知道刚入门学c等等几十行的简单小计算程序时学到的那种思路,因为那些是“输入-输出”式的简单函数。 如果你学习交互式程序设计,假设有10个独立的(貌似循环)的功能行为,那么凡是交互部分,都必须“断开”,然后每一个片段都必须是事件驱动(包括定时器事件驱动),这样才能组合成为一个完善的应用。难道你要写10个死循环,然后再胡乱地DoEvents调用?这是编程大忌。
  • 打赏
  • 举报
回复 1
DoEvents 是 vb(4、5、6)的产物,因为那是单线程的。 它的机制是将你的应用中尚未触发的windows消息大乱次序、提前触发。比如说你在鼠标点击某个控件时会去调用过程a,在鼠标在此控件移动时会去调用过程b,同时在timer定时器到时时回去调用过程c,那么你会看到DoEvents 造成了在a尚未结束时反复调用了b、c等等过程,主线程中明明是顺序的代码,调用时一片混乱无法调试。而且往往会导致事件的爆炸性的循环调用(类似于无线递归没有节制),直至系统资源耗尽而崩溃。 正常的主线程异步操作,是可以明确地知道过程在主线程中被调用的先后次序的,可以明白地调试代码(明白地看懂调用堆栈)。主线程都是先调用完a,然后才可能调用b、c,并不是在过程中去拆自己的台。因此如果需要循环触发,那么就使用定时器。 DoEvents是vb那个时代的产物,应该终止与vb6(1998年)的时代。如果你要简单移植vb6的程序,可以用它。如果不是就不要用它。
masanaka 2015-12-11
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
另外,在应用程序设计中搞“死循环”这是很令人不忍看、不忍“闻”的设计方式。如果你认为主线程经常要重复干一件(逻辑的)事儿,就必须写一个死循环,那么我只能说我们是绝对不用这样的程序员的。 在设计上,除非万不得已实在活不下去了,否则不允许随便写“死循环、阻塞”的代码。 写死循环,是因为有些人只知道刚入门学c等等几十行的简单小计算程序时学到的那种思路,因为那些是“输入-输出”式的简单函数。 如果你学习交互式程序设计,假设有10个独立的(貌似循环)的功能行为,那么凡是交互部分,都必须“断开”,然后每一个片段都必须是事件驱动(包括定时器事件驱动),这样才能组合成为一个完善的应用。难道你要写10个死循环,然后再胡乱地DoEvents调用?这是编程大忌。
wjq 2015-12-11
  • 打赏
  • 举报
回复
1:不要在UI线程去写这种死循环 2:Timer分2种:1)Treading里的Timer这是多线程的一种封装,2)Windows.Form里的Timer,这是对windows消息机制的封装 3:你应该UI只管显示,循环读数据之类的事,再开一个线程去做。新线程里乖乖的用Sleep

110,499

社区成员

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

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

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