2

In my program i'm starting for loop using button, I want to break this for loop using another button. For example:

private void button1_Click(object sender, EventArgs e)
{
    for( int i = 0; i <  var; i++)
    {
        //doing something
    }
}

And using second button break loop,

private void button2_Click(object sender, EventArgs e)
{
    //breaking loop;
}

Need help :)

1
  • @Legends No, you cannot. Both event handlers run on a UI thread, so button2_Click will not be entered until button1_Click is over. Commented Sep 30, 2017 at 11:14

3 Answers 3

6
  1. Set a flag in button2_Click() method and check it in the button1_Click()'s loop.

  2. In order to process Windows events and allow button2_Click() handle to run while iterating, add Application.DoEvents() in your loop:

bool breakLoop = false;

private void button1_Click(object sender, EventArgs e)
{
    breakLoop = false;
    for( int i = 0; i < var && !breakLoop; i++)
    {
         //doing something
         Application.DoEvents();
    }
}

private void button2_Click(object sender, EventArgs e)
{
    breakLoop = true;
}
Sign up to request clarification or add additional context in comments.

2 Comments

@dasblinkenlight: actually, it can with the help of Application.DoEvents(). The latter invokes a callback from running code in the UI thread to the Windows message pump, which in turn processes newly came messages and calls appropriate event handlers including button2_Click(). There may be some latency in UI response depending on what //doing something actually does, though.
@DmitryEgorov The line breakLoop = true; in button1_Click is wrong. It should be breakLoop = false;. Please correct that.
0

You cannot do that, because the loop in button1_Click event handler will be holding the UI thread. Your user interface will not respond to any event, showing hourglass icon, until the loop is over. This means that button2_Click cannot be entered until button1_Click has completed.

You need to replace the long-running loop from the event handler with something that runs outside the UI thread. For example, you can use Tasks, which can be cancelled using CancellationToken (related Q&A).

Comments

0

Arguably it would be better to use threads and cancellation tokens in some form, rather than the Application.DoEvents(). Something like this:

private CancellationTokenSource loopCanceller = new CancellationTokenSource();

private void button1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew(() =>
    {
        try
        {
            for (int i = 0; i < 100; i++)
            {
                this.loopCanceller.Token.ThrowIfCancellationRequested(); // exit, if cancelled

                // simulating half a second of work
                Thread.Sleep(500);

                // UI update, Invoke needed because we are in another thread
                Invoke((Action)(() => this.Text = "Iteration " + i)); 
            }

        }
        catch (OperationCanceledException ex)
        {
            loopCanceller = new CancellationTokenSource(); // resetting the canceller
            Invoke((Action)(() => this.Text = "Thread cancelled"));
        }
    }, loopCanceller.Token);
}

private void button2_Click(object sender, EventArgs e)
{
    loopCanceller.Cancel();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.