C# 在事件句柄完成第一次调用之前,如何防止任何按钮单击事件排队
我想防止按钮点击排队。在测试中,我有一个表单、一个按钮,在代码中,我有一个事件处理程序:C# 在事件句柄完成第一次调用之前,如何防止任何按钮单击事件排队,c#,winforms,event-handling,C#,Winforms,Event Handling,我想防止按钮点击排队。在测试中,我有一个表单、一个按钮,在代码中,我有一个事件处理程序: private void button1_Click(object sender, EventArgs e) { if (_codeRunning) return; _codeRunning = true; //Application.DoEvents(); //button1.Enabled =
private void button1_Click(object sender, EventArgs e)
{
if (_codeRunning)
return;
_codeRunning = true;
//Application.DoEvents();
//button1.Enabled = false;
_click ++;
Debug.WriteLine("Click Number: " + _click);
Task.Delay(5000).Wait();
//button1.Enabled = true;
_codeRunning = false;
}
当我运行debug并快速单击按钮两次、三次或四次时,debug输出会在最后一次单击后大约五秒钟显示每次单击。我希望它显示的是一次单击并删除其余部分,直到第一个事件完成
我还尝试禁用按钮,以及从按钮单击事件中临时删除处理程序。结果都是一样的。当你像这样挂断UI线程时,你会遇到各种各样的麻烦。这当然是其中之一,当用户疯狂地敲打按钮试图让一些明显的事情发生时,没有什么令人愉快的事情发生。当然,这些点击不会丢失,它们存储在消息队列中。要激活事件处理程序,请在事件处理程序停止运行时再次单击事件处理程序 了解如何使用BackgroundWorker或Task类来避免此类问题非常重要。仅设置按钮的Enabled属性就足以解决此问题 从技术上讲,清除消息队列中的鼠标单击是可行的。但做起来很难看,需要品沃克。我会犹豫不决地发布替代方案,不要认为这是一个好策略。您需要阅读一些文章来了解为什么DoEvents()是一个危险的方法
private void button1_Click(object sender, EventArgs e) {
button1.Enabled = false;
button1.Update();
'' long running code
''...
Application.DoEvents();
if (!button1.IsDisposed) button1.Enabled = true;
}
Update()调用确保用户得到反馈,他需要知道反复敲打按钮不会有任何用处。DoEvents()调用将调度所有排队的鼠标单击,由于按钮仍然处于禁用状态,因此不会发生任何操作。IsDisposed测试对于解决DoEvents()的问题至关重要,它可以确保在代码运行时,当用户单击窗口的关闭按钮时,程序不会崩溃
使用中的沙漏类提供更多反馈。我有一个按钮,单击事件将运行一个方法。同样的问题也发生了,当用户多次单击时,该方法被多次触发。因此,我创建了一个布尔值,并在方法启动时更改了它的值
private bool IsTaskRunning = false;
private void MyMethod()
{
if ( IsTaskRunning==false )
{
IsTaskRunning=true;
// My heavy duty code that takes a long time
IsTaskRunning=false; // When method is finished
}
}
因此,现在该方法只有在上次完成时才运行。您正在使用5秒的延迟来绑定UI线程,因此在代码完成之前,它不会将任何进一步的窗口消息出列。您需要将缓慢的代码移入(比如)后台工作程序,然后设法知道是否有一个正在进行中。这种行为发生的原因是windows将消息循环中的所有单击排队。你的主线程无法删除它们,因为他等待了5秒。也许你可以将你的局部变量_coderrunning设置为true(你已经设置了),然后启动一个新的线程来执行所有其他的工作,包括将_coderrunning设置为false。如果这样做,主线程可以删除所有单击消息(是的,它也会调用事件处理程序,但是如果代码正在运行,并且什么也不会发生,则返回)。也许你必须声明你的代码运行是不稳定的。@Damien\u不信者Deam 9秒太慢了…:-(优雅且有效!这个好的欺骗怎么可能不比公认的答案好?这不如公认的答案好,因为按钮仍然处于启用状态,因此从UI的角度来看,用户可能认为他们一直按下按钮,它会做一些事情,但事实并非如此。禁用按钮可能更可取。