本人是delphi ,
btnStart.Enabled:=false;
之间做一个递归比较耗时,
btnStart.Enabled:=true;
发现在Enabled:=false; 之后还是会触发用户重复clik,诧异了。 百度了一下,发现 C# winform也是有这个问题,同一套机制。百度到下方文章,
避免用户重复点击按钮(使用Enable:=False,消息繁忙时会有堵塞的问题,只能改用Sleep) - findumars - 博客园
https://www.cnblogs.com/findumars/p/6347945.html
// 现象描述: // 用户点击按钮后程序开始繁忙工作,这时候用户不知道是否成功,就继续点几次 // 采用Enalbe = false ... = true的方式发现还会触发点击,分析原因如下 // 当程序繁忙的时候消息被堵住了 // 所以点击消息还会被处理 // 将队列里的消息处理掉后才打开按钮的Enabled private void button1_Click(object sender, EventArgs e) { button1.Enabled = false; Thread.Sleep(2000); richTextBox1.AppendText(Environment.TickCount.ToString() + "/r/n"); Application.DoEvents(); // 关键语句 button1.Enabled = true; }
而我改成: 就可以了。
procedure TForm1.btnStartClick(Sender: TObject); begin btnStart.Enabled:=false; ErgodicDirectory('');//递归去做的比较耗时的事情 Application.ProcessMessages(); btnStart.Enabled:=true;//在恢复之前 用Application.ProcessMessages(); end;
application.ProcessMessages的主要作用使程序在循环时能够相应外界事件。
一般情况下,程序在循环的时候不响应外界事件。直到循环结束为止才能接受和响应外界事件。
application.ProcessMessages可以有效的解决循环循环的独占问题,能够暂时中断应用程序的执行。
比如,你要设计一个计算,这个计算需要循环10000次。当循环开始到500次的时候,用户突然不想计算下去了,它想取消这个计算,
这时候你就可以设置一个cancel按钮,然后在循环体内部合适的位置application.ProcessMessages。来处理cancel按钮的信息,中断循环。
如果你在循环体内没有application.ProcessMessages这句。当循环开始后,程序就被10000次的这个循环独占了,直到循环结束为止。在循环的期间,用户的按什么按钮都没有用。
平时也是常用 application.ProcessMessages 来 防止程序假死。想不到这里也需要用到它。