Peter
Peter

Reputation: 33

How can I stop my while loop?

I would like to use the following code in C# but I just can't seem to get out of it. I would like to terminate the application if the user presses a key or moves the rodent (aka mouse). Here is my code (no laughing!).

private void frmDots_KeyDown(object sender, KeyEventArgs e)
{
  bgNotClicked = false;
  Close();
}   

private void frmDots_Click(object sender, EventArgs e)
{
  bgNotClicked = false;
  Close();
}   



  while (bgNotClicked)
  {

    // Clear the first element in our XY position. This is the reverse of the way I   normally create the dots application
    System.Drawing.Rectangle clearDots = new System.Drawing.Rectangle(Dots.PositionX[iCounter], Dots.PositionY[iCounter], 8, 8);

    // Create the black color and brush to clear dots
    Color clearDotsColor = Color.Black;
    SolidBrush clearDotsBrush = new SolidBrush(clearDotsColor);

    // Finally clear the dot
    e.Graphics.FillEllipse(clearDotsBrush, clearDots);


    GetRandomPosition(iCounter);

    // Fill the elements to display colors on the displays canvas
    System.Drawing.Rectangle colorDots = new System.Drawing.Rectangle(Dots.PositionX[iCounter], Dots.PositionY[iCounter], 8, 8);

    // Create the color and brush to show dots
    Color colorRandom = GetRandomColor();
    SolidBrush colorBrush = new SolidBrush(colorRandom);

    // Finally show the dot
    e.Graphics.FillEllipse(colorBrush, colorDots);

    Thread.Sleep(5);

    iCounter++;
    if (iCounter == 399)
    {
      iCounter = 0;
    }

  }
}

Upvotes: 3

Views: 8204

Answers (11)

AwesomeHemu
AwesomeHemu

Reputation: 11

Use Environment.Exit(2); (or Environment.Exit(1) it really doesn't make a difference) to exit out of the application.

Upvotes: 0

gehsekky
gehsekky

Reputation: 3219

Exit While

...................

Upvotes: -3

Kirtan
Kirtan

Reputation: 21695

You can exit the loop using the break statement.

EDIT: OK, I take back the flag thing!

Upvotes: 0

Jeff Youel
Jeff Youel

Reputation: 653

I think using a Timer fits the Windows event-driven model better than the busy wait while loop. You might try something like this:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private int iCounter = 0;

    private void Draw()
    {
        // ....
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Draw();

        iCounter++;
        if(iCounter == 399)
        {
            iCounter = 0;
        }
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Interval = 5;
        timer1.Enabled = true;
    }

    private void Form1_Click(object sender, EventArgs e)
    {
        timer1.Enabled = false;
        Close();
    }

    private void Form1_KeyDown(object sender, KeyEventArgs e)
    {
        timer1.Enabled = false;
        Close();
    }
}

Upvotes: 1

Cyberherbalist
Cyberherbalist

Reputation: 12309

If you're looping like that you need to give the application a moment to process the events that you're hoping will cause the interruption. This is the job of the DoEvents method.

private bool WeAreDone = false;

private void DoingIt()
{
    while (true)
    {
        Application.DoEvents();
        if (WeAreDone)
        {
            break;
        }
    }
}

private void InterruptButton_Click(object sender, EventArgs e)
{
    WeAreDone = true;
}

Upvotes: 1

hmcclungiii
hmcclungiii

Reputation: 1805

Try moving the loop into a BackgroundWorker's DoWork event handler. Then your GUI will still be responsive and instead of that nasty variable, you can just call the CancelAsync method to stop the loop.

Upvotes: 0

Reed Copsey
Reed Copsey

Reputation: 564413

Edit:

After seeing your edit, this is definitely your problem. The issue is that your while loop blocks the main UI thread, so it never handles the Windows Messages which trigger your key press/mouse/etc handlers.

You have a couple of options - you can either move some of this onto a separate thread, do what I suggested below, or add a call to Application.DoEvents in your while loop. This would allow your event handlers to run, which would in turn set bgNotClicked = false;. Right now, that's never occurring because your UI is blocked entirely.


Original Post:

If you're doing this loop in your UI thread, you're going to need to rethink the design a bit.

Setting bgNotClicked = false; somewhere in an event handler will work, but only if your event handler is able to run. If you're doing the above code in the UI thread, it will block your UI thread indefinitely, preventing the event handler from firing.

I would recommend reworking this to be based off a timer (so it runs repeatedly on regular intervals), instead of locked into a while loop. This would allow your other UI events to fire between runs, and instead of setting bgNotClicked = false;, your event handler could just set the timer to be not enabled.

Upvotes: 4

Garrett
Garrett

Reputation: 1790

Your "busy waiting" strategy is poor design. Instead, you should use event handlers that are fired:

  • On keypress.
  • When the mouse is moved.

In either case, you can respond by terminating the application.

Upvotes: 6

danish
danish

Reputation: 5610

This does not seems to be the correct way. .Net Framework has provided you with the events to handle the KeyPress and MouseMove/Click actions. Why are you not using them?

Upvotes: 0

Tony
Tony

Reputation: 1714

The break keyword will terminate a loop. In this case, when you hit the case where you want to stop the loop, you would just use break;.

Upvotes: 1

AndreiM
AndreiM

Reputation: 4598

Your bgNotClicked variable needs to be set to false by your event handler for key-press.

If the rodent is moved by your mouse, you would need a similar mouse event handler.

Upvotes: 3

Related Questions