LomidzeAlex
LomidzeAlex

Reputation: 41

C# - Break Loop from another button

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 :)

Upvotes: 2

Views: 732

Answers (3)

Avo Nappo
Avo Nappo

Reputation: 630

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();
}

Upvotes: 0

Dmitry Egorov
Dmitry Egorov

Reputation: 9650

  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;
}

Upvotes: 6

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726809

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).

Upvotes: 0

Related Questions