【问题标题】:C# do while loop start stopC#做while循环开始停止
【发布时间】:2011-09-25 03:37:24
【问题描述】:

我正在尝试为此循环制作一个停止按钮,但它无限期运行,当我单击按钮 2 时没有任何反应

bool dowhile = false;
private void button1_Click(object sender, EventArgs e)
{
    do
    {
        for (int i = listbox1.Items.Count - 1; i >= 0; i--)
        {
            string textstring = listbox1.Items[i].ToString();
            richTextBox1.AppendText("" + textstring + ": Done\n");
            Thread.Sleep(1000);
        }
    } while (!dowhile);
}
private void button2_Click(object sender, EventArgs e)
{
    this.dowhile = true;
}

我哪里出错了?

对不起,“lvlchanger”错字,代码现在没问题,没有任何遗漏

我也在寻找一个不那么长的解决方法:))

【问题讨论】:

  • 你如何改变'lvlchanger'?
  • 找到这个lvlchanger 对象的所有cmets/answers 到底在哪里?也许我会失明,但我在代码中看不到它,我的浏览器搜索也没有。据我所知,该问题尚未被编辑以修改代码......有人愿意填写我吗?
  • 感谢您的澄清。为了回应您对“不那么长的修复”的要求,不幸的是没有这样的事情。正如我的回答所解释的,一个线程一次只能做一件事。由于许多复杂的原因,DoEvents 的 hacky 修复是一个非常糟糕的主意。我不建议任何人使用它,除非他们真正了解多线程所涉及的问题。如果他们这样做了,他们可能会改用正确的方法。按照 MSDN 页面上显示的示例,用BackgroundWorker 替换整个位绝对是最简单的答案,也是最好的答案。
  • 正如我所说.. DoEvents 在这种情况下不起作用
  • BackgroundWorker 将使我的 4page 代码成为一部小说

标签: c# loops for-loop while-loop do-while


【解决方案1】:

在您的button1_Click 完成之前,系统无法处理消息队列中的任何内容(即按钮单击、重绘等) - 它永远不会。这正是导致所有那些“{blah} 没有响应”消息的原因 - 没有及时响应消息队列的代码。

基本上,不要那样做。 hacky 修复将是一些 DoEvents(),但不!正确地做;基本上,改为处理来自button2_Click 的事件。也许您应该从计时器滴答声中运行刷新?

【讨论】:

    【解决方案2】:

    Thread.Sleep 几乎总是错误的方法;当您发现自己想在代码中使用类似的东西或 Application.DoEvents 时,是时候退后一步,想想您真正在做什么以及为什么它不起作用。你的未来应该有一个新的设计。

    这里真正的问题是您在 UI 线程上工作,这会阻止用户与您的应用程序交互。 循环已经完成处理之后,您对 Button2 的点击会得到识别和处理,此时它绝对什么都不做。

    这是因为线程一次只能完成一项任务。而且,事实上,Thread.Sleep(100) 只会让情况变得更糟,因为它会强制线程旋转并且 什么都不做 100 毫秒。循环完成需要多 100 毫秒,而绝对没有任何增益。

    这个(常见)问题的正确解决方案是使用BackgroundWorker class 之类的东西将循环转到一个单独的线程上。 MSDN 条目有一个很好的使用示例,包括您的特定用例:允许用户取消长时间运行的后台任务。

    【讨论】:

      【解决方案3】:
      private void button1_Click(object sender, EventArgs e)
      {
          bool dowhile = false;private void button1_Click(object sender, EventArgs e){
          do 
          {
              for (int i = listbox1.Items.Count - 1; i >= 0; i--)
              {
                  string textstring =listbox1.Items[i].ToString();
                  richTextBox1.AppendText("" + textstring + ":` `Done\n");
                  Thread.Sleep(1000);
              }
          } while (!lvlchanger && dowhile == false);
      }
      
      private void button2_Click(object sender, EventArgs e)
      {
          this.dowhile = true;
      }
      

      【讨论】:

      • 在此处显示代码的行数没有限制。但是您需要使用不同的格式化技巧:选择整个块,然后单击工具栏中的{} 按钮。反引号仅适用于 inline 代码 sn-ps。将所有内容都塞在一行中会让人难以阅读,就像任何语言的连续句子一样!
      • 但无论如何,您的答案实际上向我们展示了什么?我看不出您对原始代码进行了任何更改。
      • 更改了这一行 while (!dowhile); with while (!lvlchanger && dowhile == false);
      【解决方案4】:

      Application.DoEvents() 添加到循环中以允许应用程序处理来自其他来源的事件。

      /编辑 这应该可以,但是...

      “这几乎不是正确的答案”——科迪·格雷

      【讨论】:

      • 想想小猫!好的,这会起作用,但它(IMO,不仅限于我)是一种非常老套的方法。
      • 是的,我知道,懒惰的答案,我正在考虑接受的答案,但不知道如何措辞。我会留下这个作为警告......
      猜你喜欢
      • 1970-01-01
      • 2017-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      • 2018-08-22
      相关资源
      最近更新 更多