C# do while循环开始停止

发布于 2024-11-17 20:17:33 字数 604 浏览 3 评论 0原文

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

我也在寻找一个不太长的修复程序:))

I am trying to make a stop button for this loop but it runs indefinite, nothing happens when i click button 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;
}

where do i go wrong ?

sry for the "lvlchanger" typo, code is ok now, nothing missing

i'm also looking for a not-so-long fix on this :))

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

迷荒 2024-11-24 20:17:33

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

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

The system can't process anything from the message queue (i.e. button clicks, repaints, etc) until your button1_Click completes - which it never will. This is exactly what causes all those "{blah} is not responding" messages - code that doesn't respond to the message queue promptly.

Basically, don't do that. A hacky fix would be some DoEvents(), but NO! do it properly; basically, handle the event from button2_Click instead. Perhaps you should run the refreshes from a timer tick?

月野兔 2024-11-24 20:17:33

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

这里真正的问题是您正在 UI 线程上工作,这会阻止用户与您的应用程序交互。在循环完成处理之后,您对 Button2 的点击将被识别并处理,此时它绝对不会执行任何操作。

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

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

Thread.Sleep is almost always the incorrect approach; when you find yourself wanting to use something like it or Application.DoEvents in your code, it's time to take a long step back and think about what you're really doing and why it isn't working. A new design should be in your future.

The real problem here is that you're doing work on the UI thread, which blocks the user from interacting with your application. Your click on Button2 is getting recognized and processed after the loop has already finished processing, at which point it does absolutely nothing.

This is because threads can only complete one task at a time. And, in fact, Thread.Sleep(100) only makes this worse, because it forces the thread to spin and do nothing for 100 milliseconds. That's 100 more milliseconds it will take for the loop to complete for absolutely no gain.

The correct solution to this (common) problem is to spin the loop off onto a separate thread, using something like the BackgroundWorker class. The MSDN entry has a very good example of its use, including your specific use case: allowing the user to cancel a long-running background task.

月下伊人醉 2024-11-24 20:17:33
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;
}
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;
}
作妖 2024-11-24 20:17:33

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

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

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

Add an Application.DoEvents() to the loop to allow the application to process events from other sources.

/EDIT
This should work, but...

"This is almost never the correct answer" - Cody Gray

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文