【问题标题】:Need to click button twice to have an effect需要点击按钮两次才能生效
【发布时间】:2021-05-28 11:10:35
【问题描述】:

该应用程序是一个机器控件,因此它需要访问 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-handling focus


    【解决方案1】:

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

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

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

    while (!Stop)
    {
        await Task.Delay(50);
    
        // or
    
        await Task.Run(() => Thread.Sleep(50));
    }
    

    UI 现在应该可以响应了。

    后者是模拟同步代码,把它代替Sleep,如果有modify UI,别忘了调用。

    【讨论】:

      【解决方案2】:

      谢谢!我不知道 Doevents 的含义,使用 async 和 await 也很简单。我添加了一个计数器来向自己展示玩具示例正在做我认为的事情。为了使答案完整并帮助像我这样可能为同一问题搜索答案的其他菜鸟,这里再次提供完整示例。这可以按需要工作(单击即可停止),并且如果主窗体在未单击停止的情况下关闭,则不会使 RunMachine() 运行。 (我的真实应用程序在表单关闭事件中有足够的代码来防止这种情况发生,但我当然不知道这个陷阱。)

          bool Stop = true;
      
          private async void Start_button_Click(object sender, EventArgs e)
          {
              await RunMachine();
          }
      
          private void Stop_button_Click(object sender, EventArgs e)
          {
              Stop = true;
          }
      
          internal async Task RunMachine()
          {
              Status_label.Text = "started";
              Stop = false;
              int i=0;
              do
              {
                  await Task.Delay(500);
                  Status_label.Text = i.ToString();
                  i++;
              } while (!Stop);
              Status_label.Text = "Stopped";
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-25
        • 2022-07-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多