首页 > 解决方案 > 需要点击按钮两次才能生效

问题描述

该应用程序是一个机器控件,因此它需要访问 ui 以显示状态等(我知道,这违背了将 UI 和工作代码分开的建议,但至少目前是这样)。问题归结为:当一个按钮事件处理程序未完成时,需要单击另一个按钮两次。第一次单击将焦点放在按钮上,下一次单击会触发事件。

这是简化到极端的问题。有两个按钮和一个标签。停止按钮需要单击两次才能停止机器:

bool Stop = true;

private void Start_button_Click(object sender, EventArgs e)
{
    RunMachine();
}

private void Stop_button_Click(object sender, EventArgs e)
{
    Stop = true;
}

private void RunMachine()
{
    Stop = false;
    Status_label.Text = "Running";
    do
    {
        Application.DoEvents();
        Thread.Sleep(50);
    } 
    while (!Stop);
    Status_label.Text = "Stopped";
}

如何使按钮对第一次点击做出反应?

标签: c#event-handlingfocus

解决方案


DoEvents()不好。不要使用它。

如果您必须使用它(例如作为解决方法),那么您正在增加技术债务并可能在未来支付,类似于您的情况。

更好的方法是在任务内运行工作并使用取消令牌,但在您的情况下,所需的最小修改是这样的(将async修饰符添加到方法中):

while (!Stop)
{
    await Task.Delay(50);

    // or

    await Task.Run(() => Thread.Sleep(50));
}

UI 现在应该可以响应了。

后者是模拟同步代码,把它代替Sleep,如果需要修改UI不要忘记调用。


推荐阅读