Home > Mobile >  While Loop Freezing C# Program
While Loop Freezing C# Program

Time:04-17

I'm having an endless stream of problems with the Blackjack program I'm making for one of my final projects. While I've used while loops a lot, in this instance whenever I instantiate one it freezes the windows forms app and won't allow any input.

I've tried doing the while loop based on int values, putting it in the main method, and trying to re-write it several times with no luck. Here's an example, I want the player's turn to last until they hit "stand".

public bool yourTurn;
    public int num = 0;
    public static Random rnd = new Random();

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        yourTurn = true;
        Play();
    }

    private void button3_Click(object sender, EventArgs e)
    {
        yourTurn = false;
    }

    private void Play()
    {
        button1.Visible = false;

        while (yourTurn)
        {
            num  ;
            label1.Text = num.ToString();
        }
    }

    private void EndGame()
    {
        yourTurn = false;
        MessageBox.Show("Game Ended");
    }

CodePudding user response:

The thing you need to understand about windows forms programs is that there is just one thread that does everything. When that thread is not running your code it is off somewhere else doing important things like drawing the user interface

Your user moves the mouse over your program, they click stuff and they press keys on the keyboard. These things cause huge numbers of tiny messages to be posted into a queue that is dedicated just to your program. Windows posts the messages and it keeps an eye on the queue. When the thread that runs your program is not actively running your code it is consuming these messages. Mostly they're probably thrown away, sometimes they lead to actions, like if you have a button click handler and Windows posts a message that the user has clicked on button X, then the consuming thread comes into your code and starts doing those things you've coded into your click handler

It is absolutely critical that you let this thread go; that your click handler finishes its work quickly and you release that thread/free it up to go back to wherever it normally lives, doing the thing it normally does (processing the messages). If you hold it up for a long time or forever, windows will notice that the message queue is growing and growing, no longer being consumed because you've trapped the thread - the window acquires a "Not responding" message and fades out- Windows does this when the message queue hasn't been consumed for longer than a particular timeout

Doing something like this will trap the UI thread forever:

bool keepLooping = true;

void ButtonX_Click(object sender, EventArgs e){
  while(keepLooping)
    Thread.Sleep(100);
}

Buttony_Click(object sender, EventArgs e){
  keepLooping = false;
} 

If you click buttonX first, it's game over; the UI thread will enter the click handler and never be able to escape. It doesn't matter that you have another click handler that would break the loop. If the thread is trapped in handler X and your user clicks button Y, the message that they clicked the button will be posted into the queue, but the UI thread is already trapped inside handler X and will never be allowed to go back to consuming the queue to discover that message; the handler for Y will never be run because the UI thread is trapped in X, so the variable will never go false, releasing the thread

Always be mindful of this; your event handlers have to be capable of finishing, and quickly, to maintain a good experience, or they have to contain specified points where you release the thread to going back to doing what it normally does, like an await instruction of an synchronous operation. Even if your code is some simple single "download a 20 gigabyte file" instruction, if you do it via some way that occupies the attention of the UI thread for the entire time it's downloading, you'll also get a "not responding" - this "do not occupy the attention of the UI thread for a long time" is crucial to having a program that doesn't freeze/hang

  • Related