C# do while loop start stop
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 :))
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?
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.
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;
}
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
精彩评论