【问题标题】:How to avoid repeated while loops with C# event handler?如何使用 C# 事件处理程序避免重复的 while 循环?
【发布时间】:2018-02-17 12:28:42
【问题描述】:

Windows 窗体 应用程序中,我有一个 ComboBox 元素,并且需要在 ComboBox 元素更改时定期运行一些代码片段。

代码的问题是,当 ComboBox Text 将 A 更改为 B 或反之亦然时,事件处理程序触发器和之前的 while(true) 循环 仍在运行。

当事件处理器被触发时,需要运行一个无限循环。

private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    string status = comboBox.SelectedItem.ToString();

    Task.Run(async () =>
    {
        while (true)
        {
            // Running on ui thread
            datagrid.BeginInvoke((MethodInvoker)delegate
            {
                status = comboBox.SelectedItem.ToString();
            });

            if (status == "A")
            {
                Work();
            }

            else if (status == "B")
            {
                anotherWork();
            }
            else if (status == "C")
            {
                someWork();
                break;
            }

            await Task.Delay(3000);
        }
    });
}

尝试了 ManualResetEvent、CancellationTokenSource 和 bool check,但都没有解决问题。

防止重复while循环的最佳做法是什么?

编辑:已经实现了计时器,但想要使用 while 循环技巧。我以错误的方式进行布尔检查,欧文的回答被接受了。

【问题讨论】:

  • 你为什么陷入循环?你考虑过使用Timer吗?
  • 丹尼尔是正确的,您应该使用计时器。也就是说,解决您所拥有的问题的方法是拥有一个私有标志bool _isInfiniteLoopRunning = false;,并在您启动无限循环时将其设置为 true。在事件处理程序中,在开始循环之前检查该标志。如果为真,则退出处理程序而不启动循环。什么是“布尔控制”?那是什么意思?没关系 - 只需使用计时器。
  • but none of them solved the problem. 对于每一次尝试,您实际上做了什么,他们以什么方式未能解决问题?
  • @EdPlunkett 我的意思是布尔检查,就像下面的 Owen Pauling 回答。
  • 我不明白为什么人们仍然投票反对。这是一个清晰而明智的问题。我已经想到了计时器,但只是想学习使用 while 循环的技巧。

标签: c# winforms while-loop event-handling async-await


【解决方案1】:

添加一个布尔值来检查循环是否正在运行:

private bool _loopRunning;

private void comboBox_SelectedIndexChanged(object sender, EventArgs e)
{
    if(_loopRunning)
    {
        return;
    }

    _loopRunning = true;

    string status = comboBox.SelectedItem.ToString();

    Task.Run(async () =>
    {
        // stuff

        _loopRunning = false;
    });
}

【讨论】:

  • 任务完成后别忘了清旗:)
  • 我已经完成了这个方法,但是当事件处理程序触发两次 (A -> B) 时。上一个循环仍在运行
  • 事件处理程序确实触发,但它立即返回。这不是你想要的吗?
  • 可以想象,由于涉及多个线程,因此可能同时发生对该处理程序的两个单独调用,并且第二个调用可能在设置变量之前通过布尔检查。使用lock 语句来控制对布尔变量的访问可能是个好主意。但是,我不确定这会在 UI 上下文中产生什么后果。
  • 我上周实施方式错误,现在再次检查并正常工作,接受了欧文的回答。
猜你喜欢
  • 1970-01-01
  • 2013-01-06
  • 1970-01-01
  • 1970-01-01
  • 2016-09-27
  • 1970-01-01
  • 2012-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多