各位大神们,我写了一个for循环,任务是从仪表中采数,经过一个算法,把最终结果填入表格,问题是我在for循环中加了一个延时小程序,为了等待仪表输出稳定再采数,但是这样造成了我的界面假死,for循环由一个button控制开始,我加一个button任意时刻中断这个for循环,但是for循环跑起来,所有button都点不了,这要怎么解决呀,下附延时小程序
AutoResetEvent MyDelayEvent = new AutoResetEvent(false); //定义事件
public void myDealyTime(int time)
{
System.Timers.Timer MyDelayTimer = new System.Timers.Timer(time); //设置定时器
MyDelayTimer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_TimesUp);
MyDelayTimer.AutoReset = true; //每到指定时间Elapsed事件是触发一次(false),还是一直触发(true),要用true会复位时间。
MyDelayTimer.Enabled = true; //是否触发Elapsed事件
MyDelayTimer.Start();
MyDelayEvent.WaitOne();
MyDelayTimer.Dispose();
Console.WriteLine("aa");
}
https://blog.csdn.net/doyoucool/article/details/74516460 private void Timer_TimesUp(object sender, System.Timers.ElapsedEventArgs e)
{
MyDelayEvent.Set();
Console.WriteLine("bb");
延时是在网上找的https://blog.csdn.net/doyoucool/article/details/74516460
AutoResetEvent MyDelayEvent = new AutoResetEvent(false); //定义事件
public void myDealyTime(int time)
{
System.Timers.Timer MyDelayTimer = new System.Timers.Timer(time); //设置定时器
MyDelayTimer.Elapsed += new System.Timers.ElapsedEventHandler(Timer_TimesUp);
MyDelayTimer.AutoReset = true; //每到指定时间Elapsed事件是触发一次(false),还是一直触发(true),要用true会复位时间。
MyDelayTimer.Enabled = true; //是否触发Elapsed事件
MyDelayTimer.Start();
MyDelayEvent.WaitOne();
MyDelayTimer.Dispose();
Console.WriteLine("aa");
}
https://blog.csdn.net/doyoucool/article/details/74516460 private void Timer_TimesUp(object sender, System.Timers.ElapsedEventArgs e)
{
MyDelayEvent.Set();
Console.WriteLine("bb");
延时是在网上找的https://blog.csdn.net/doyoucool/article/details/74516460
解决方案 »
- C#数据库问题
- 散分
- 如何做winfrom项目打包
- 几个页面 用iframe 框架 其中一个页面是在线聊天室 用div.innerhtml 来显示聊天内容 显示问题
- 关于ArrayList 里面存放对象(比如:ArrayList )后的访问操作的问题
- 无限连动 递归
- 从索引 0 处开始,初始化字符串的格式不符合规范怎么回事
- ·····如何用反射调用继承类里面的方法?
- 请问《程序员》和《开发高手》如何才能买到?
- 未能找到类型或命名空间名称“DBUser”(是否缺少 using 指令或程序集引用?)
- Winform怎么把Bitmap旋转自定义的角度?
- C# DLL方式读取M1非接触式卡SN码(已有C++程序,不知道指针参数怎么设置)
界面假死是因为主线程被阻塞了
大多数耗时的操作和处理推荐使用
线程或者Task来完成
与UI交互使用委托
如果不熟悉,可以用backgroundworker控件来实现
这就是一个只会写简单的数学计算小函数的弊病。一旦开发交互操作程序,你不打算阻塞这个所谓 for 循环过程,那么你就不可能写一个同步 for 循环,你必须会学异步 for 循环。没学过异步 for 循环语句怎么写的话,那么你就设计一个 timer 来模拟 for 循环反复调用并且递加循环变量的几行代码,把这个机制封装到一个单独的对象中以免循环控制变量跟其它变量相冲突。总之,这里其实重点不在于子线程概念。即使是只能进行单线程编程(例如古老的 vb3、vb5 编程),你也是可以用定时器迭代模拟 for 循环的。关键就在于要有基本的意识,在 for 循环中必须交出 UI 控制权,绝不能阻塞。
这就是一个只会写简单的数学计算小函数的弊病。一旦开发交互操作程序,你不打算阻塞这个所谓 for 循环过程,那么你就不可能写一个同步 for 循环,你必须会学异步 for 循环。没学过异步 for 循环语句怎么写的话,那么你就设计一个 timer 来模拟 for 循环反复调用并且递加循环变量的几行代码,把这个机制封装到一个单独的对象中以免循环控制变量跟其它变量相冲突。总之,这里其实重点不在于子线程概念。即使是只能进行单线程编程(例如古老的 vb3、vb5 编程),你也是可以用定时器迭代模拟 for 循环的。关键就在于要有基本的意识,在 for 循环中必须交出 UI 控制权,绝不能阻塞。
大神,那意思就是说我的界面假死是因为加入了那个延时程序造成阻塞引起的吗,,还是因为for循环本身就会阻塞我是崭新崭新的小白
这就是一个只会写简单的数学计算小函数的弊病。一旦开发交互操作程序,你不打算阻塞这个所谓 for 循环过程,那么你就不可能写一个同步 for 循环,你必须会学异步 for 循环。没学过异步 for 循环语句怎么写的话,那么你就设计一个 timer 来模拟 for 循环反复调用并且递加循环变量的几行代码,把这个机制封装到一个单独的对象中以免循环控制变量跟其它变量相冲突。总之,这里其实重点不在于子线程概念。即使是只能进行单线程编程(例如古老的 vb3、vb5 编程),你也是可以用定时器迭代模拟 for 循环的。关键就在于要有基本的意识,在 for 循环中必须交出 UI 控制权,绝不能阻塞。
那我现在要解决问题的话就是要写一个异步for循环吗,那我想加一个button,在任意时刻跳出或者终止这个循环,异步for循环也是可以实现的吗
后续处理代码.......这类语句来定时,但是把这个代码写到 for 循环内部,你起码应该知道机制,这个代码所在的方法的声明上要写 async 关键字,调试时一旦执行到 Delay 这里其实方法就跳出去了,方法就结束了;然后过了500毫秒又有一个线程(系统线程池分配的任务)跳进了await 的左边或者后边的代码继续调用后续处理代码。你如果不懂异步机制,就会觉得诡异,或者就会盲目抄袭而写出逻辑上有着巨大 bug 的代码。
{
MSG msg;
// Process existing messages in the application's message queue.
// When the queue is empty, do clean up and return.
while (::PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{// has msg
if (!AfxGetThread()->PumpMessage()) break;
}
}
我就是自学新手,我平时经常这么做,没觉得有什么不妥。
DoEvents 主要是18年前移植 vb6 的语句使用,因为 vb 当时本身的语言设计是不具有多线程编程能力的,(当时)其它平台并不进行这样的操作,哪怕是单线程的 javascript 语言也不支持 DoEvents 这类操作。正常的事件处理过程,你调试一下就知道,是正常地执行完一个事件的过程,然后才执行下一个事件处理过程。而如果在一个时间处理过程中递归调用 windows 消息泵里处理后边的事件处理过程,那么就产生了逻辑上的诡异跳转,直接跳转到其它事件处理过程之后CPU上下文又跳回递归点。这在你把 DoEvents 写到循环语句中(通常你都是干这个的)时,特别是一个事件处理过程中的操作可能会造成其它事件发生时,会迅速产生逻辑混乱,以及事件级联爆炸的危险。正常的事件处理过程是不会发生这种情况的,因为没有哪个事件处理过程在设计上是在某个中间点去递归地处理其它事件的。所以 DoEvents 其实是个大坑。这很适合 vb 那类——vb 的含义本身就是“初学者编程语言”——使用,但是复杂的事件驱动设计程序则会(即使是单线程)逻辑混乱无法调试,甚至因为事件次序的混乱而产生事件组合爆炸。
t: 0,
start: function(){
.......
if(this.t<1000)
window.setTimeout(this.start, 50);
}
}
这类使用定时器的迭代循环操作。它处理循环时不是用递归,而是定时迭代,所以裸机上它一定是当前 function 运行完毕之后才执行其它的 UI 函数,所以有起码的安全。而 DoEvents 并不是基本安全的机制,不可以随便用。