gpt4 book ai didi

c# - 在第一次调用完成事件句柄之前,如何防止任何按钮单击事件排队

转载 作者:太空狗 更新时间:2023-10-29 22:58:18 25 4
gpt4 key购买 nike

我想防止按钮点击排队。在测试中,我有一个表单、一个按钮,在代码隐藏中我有事件处理程序:

    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;
}

当我运行调试并快速单击按钮两次或三四次时,调试输出会在上一次单击后大约五秒显示每次单击。我希望它显示的是单击并放下其余部分,直到第一个事件完成。

我还尝试禁用该按钮,并暂时从 Button_click 事件中删除处理程序。都是一样的结果。

最佳答案

当您像这样挂断 UI 线程时,您会遇到各种麻烦。这当然是其中之一,当用户疯狂地敲击按钮以试图让某事发生时,没有任何令人愉快的事情发生。当然,这些点击不会丢失,它们会存储在消息队列中。当您的事件处理程序停止运行时再次激活您的 Click 事件处理程序。

学习如何使用 BackgroundWorker 或 Task 类来避免此类麻烦非常重要。只需设置按钮的 Enabled 属性即可解决此问题。

从消息队列中清除鼠标点击在技术上是可行的。但是做起来很难看,它需要 pinvoke。我会犹豫地发布替代方案,不要认为这通常是一个好的策略。你需要阅读 this post深入了解为什么 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() 调用将分派(dispatch)所有排队的鼠标点击,它们没有任何反应,因为按钮仍然被禁用。 IsDisposed 测试对于解决 DoEvents() 的问题至关重要,它确保当用户在代码运行时单击窗口的关闭按钮时您的程序不会崩溃。

this post 中使用 HourGlass 类以提供更多反馈。

关于c# - 在第一次调用完成事件句柄之前,如何防止任何按钮单击事件排队,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30894162/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com