简体   繁体   中英

Problems of while(true) in C# “VS2012” {WinForm}

" int ans = 2;

    private void Form1_Load(object sender, EventArgs e)
    {
        for (int i = 0; i <21; i++)
        {
            ans = 2;
            label1.Text += i.ToString();
            while (true)
            {
                if (ans == 1)
                {
                    break;
                }
            }
        }

    }

    private void button1_Click(object sender, EventArgs e)
    {
        ans = 1;
    } "

this is a simple app

I want to print a number & then wait to the button to be clicked to break the while loop

but when I run the application , the form doesn't show .

"T think that the problem is the while (true)".

what to do?

Use a timer. Start the timer when the form loads. Each time it ticks, increment the number and display it. On button click, you just need to stop the timer.

private Timer _myTimer;
private int number = 0;
private void Form1_Load(object sender, EventArgs e)
{
    _myTimer = new Timer();
    _myTimer.Interval = 1; // 1 millisecond
    _myTimer.Tick += new EventHandler(MyTimer_Tick);
    _myTimer.Start();
}

// increments the number at timer tick
private void MyTimer_Tick(object sender, EventArgs e)
{
    number ++;
    // TODO: update UI here
}

// Stops the timer
private void button1_Click(object sender, EventArgs e)
{
    _myTimer.Stop();
} 

It's best to not use a loop here. Since this loop won't end you won't ever leave Form_Load and it won't display the form. If you were trying to do some task when the user clicks a button, why not move that logic to button1_Click ?

The correct way to implement such a task as you describe would be as such:

    private EventWaitHandle ewh = new EventWaitHandle(false, EventResetMode.AutoReset);

    private void Form1_Load(object sender, EventArgs e)
    {
        Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 26; i++)
            {
                ewh.WaitOne();
                Action updateLable = () => label1.Text = "" + i;
                label1.BeginInvoke(updateLable);
            }
        });
    }

    private void button1_Click(object sender, EventArgs e)
    {
        ewh.Set();
    }

As you can see I've replaced your busy wait (while(true)) with a .Net wait handle .

One of the answers describes a timer that acts every millisecond - that is a busy wait of sorts.

This is what async/await is for. Mark your Load() event with "async", then "await" a Task that continues when a ManualResetEvent is triggered in the Button click handler:

    private System.Threading.ManualResetEvent mre = new System.Threading.ManualResetEvent(false);

    private async void Form1_Load(object sender, EventArgs e)
    {
        for (int i = 0; i < 21; i++)
        {
            label1.Text = i.ToString();
            mre.Reset();
            await Task.Factory.StartNew(() => { mre.WaitOne(); });
        }
        button1.Enabled = false;
        label1.Text = "Done!";
    }

    private void button1_Click(object sender, EventArgs e)
    {
        mre.Set();
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM