2

我正在尝试为此循环制作一个停止按钮,但它无限期运行,当我单击按钮 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”错字,代码现在没问题,没有遗漏

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

4

4 回答 4

5

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

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

于 2011-06-29T13:06:08.463 回答
2

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

这里真正的问题是您在 UI 线程上工作,这会阻止用户与您的应用程序交互。在循环完成处理后,您对 Button2 的单击将得到识别和处理,此时它完全没有任何作用。

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

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

于 2011-06-29T13:08:12.013 回答
-1

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

/EDIT 这应该可以,但是...

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

于 2011-06-29T13:05:32.727 回答
-1
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;
}
于 2011-06-29T13:13:06.363 回答