我正在使用WinForms应用程序,我有一个用户控件。用户控件中的按钮将事件提升到要由其他代码处理的表单。其中一个按钮启动一些过程,如果它们同时运行会导致问题。我在代码中有逻辑来管理状态,因此通常用户无法运行该进程(如果它已在运行)。但是,如果用户双击该按钮,它将很快启动该过程两次,以至于我很难阻止它。

我想知道,处理这个问题的最佳方法是什么?

我首先禁用了点击事件中的按钮,但在第一次点击导致按钮被禁用之前,第二次点击进入。在代码中设置其他标志也没有捕获它。

我正在考虑在引发事件的代码上添加某种同步锁,但我想知道你是否有更好的想法。

由于这个项目大部分已完成,我正在寻找不涉及对应用程序进行彻底改写的答案(比如实现复合应用程序块),但是,我也可以随意发布这些想法,因为我可以在我的下一个项目。

有帮助吗?

解决方案

确保您的按钮禁用或您执行的任何其他锁定是您在事件处理程序中执行的/ first / thing。如果你能在第一条指令触发之前排队两次点击事件,我会感到非常惊讶,但我想如果你是在一台非常慢的计算机上,那么就有可能与其他应用程序陷入困境。

在那种情况下,请使用旗帜。

private bool runningExclusiveProcess = false;

public void onClickHandler(object sender, EventArgs e)
{
    if (!runningExclusiveProcess)
    {
        runningExclusiveProcess = true;
        myButton.Enabled = false;

        // Do super secret stuff here

        // If your task is synchronous, then undo your flag here:
        runningExclusiveProcess = false;
        myButton.Enabled = true;
    }
}

// Otherwise, if your task is asynchronous with a callback, then undo your flag here:
public void taskCompletedCallback()
{
    runningExclusiveProcess = false;
    myButton.Enabled = true;
}

如果您仍然可以两次点击这样的内容,那么请确保您不会意外地订阅doubleClick事件,或者其他任何事情都会发生。

其他提示

您是否正在处理此事件两次?

非常惊讶地发现,在您禁用该按钮之前,第二次点击即将进入。我希望确保你没有把事件挂了两次。我以前偶然做过这件事。然后,你几乎可以立即得到两个事件。

在按钮事件处理程序完成之前,不会设置该按钮上的禁用标志,并且任何其他点击将在第一次单击后面的Windows消息队列中排队。确保按钮事件处理程序快速完成以释放UI线程。有几种方法可以做到这一点,但所有这些都涉及到产生线程或保持工作线程准备就绪并等待AutoResetEvent。

您是否有机会用图标标记按钮?无论如何都要使用代码来防止一次运行两个进程,但是如果你的按钮看起来像一个传统的命令按钮(只有矩形,只有文本标签,“凸起”的表面,你可以减少双击人的一面)点击)。只是一个想法。

单击按钮后立即禁用该按钮。因此,该事件无法处理两次。处理完事件后,您可以重新启用该按钮。

如果轶事充其量,那么检查的答案就会很接近。对于没有经验的人来说,它缺少太多有意义的代码。我写过一篇关于使用Timers和Threads的文章,代码示例真的很容易理解。尝试阅读它并查看是否可以通过在新线程中运行任务进程来设置上述示例中的标志:

http://www.robault.com/category/Threading.aspx

在用户首次单击按钮并启动任务之前禁用该按钮。任务完成后,重新启用按钮。

  

我开始时禁用按钮   在点击事件但第二个   在第一次点击之前点击进入   导致按钮被禁用。   在代码中设置其他标志没有   抓住它。

鉴于WinForms本质上是单线程的,在完成第一次处理之前,第二次点击不应该被激活(除非您使用新线程或BackgroundWorkers等)。

您能告诉我们一个说明您问题的样本吗?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top