简体   繁体   中英

Proper way to add delay in my code execution

I am trying to make a very simple logic game. The idea is to see a matrix with a certain number of colored squares(buttons) then to hide them and the player has to click the colored squares. So I need a 2 second delay between the painting the squares/buttons and returning the original colors. All the code is implemented in a button_click event.

private void button10_Click(object sender, EventArgs e)
{

    int[,] tempMatrix = new int[3, 3];
    tempMatrix = MakeMatrix();
    tempMatrix = SetDifferentValues(tempMatrix);
    SetButtonColor(tempMatrix, 8);
    if (true)
    {
        Thread.Sleep(1000);
       // ReturnButtonsDefaultColor();
    }
    ReturnButtonsDefaultColor();
    Thread.Sleep(2000);

    tempMatrix = ResetTempMatrix(tempMatrix);
}

This is the whole code, but what I need is to have some delay between calling SetButtonColor() and ReturnButtonsDefaultColor() . All my experiments with Thread.Sleep() meet no success till now. I get a delay at some point, but the colored squares/buttons are never shown.

You don't see the buttons change color because the Sleep call prevents messages from being processed.

Probably the easiest way to handle this is with a timer. Initialize the timer with a 2 second delay and make sure that it's disabled by default. Then, your button click code enables the timer. Like this:

private void button10_Click(object sender, EventArgs e)
{
    // do stuff here
    SetButtonColor(...);
    timer1.Enabled = true; // enables the timer. The Elapsed event will occur in 2 seconds
}

And your timer's Elapsed event handler:

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

You can always use TPL, its the simplest solution, because you don't need to handle thread contexts or fragment your code.

private async void button10_Click(object sender, EventArgs e)
{

    int[,] tempMatrix = new int[3, 3];
    tempMatrix = MakeMatrix();
    tempMatrix = SetDifferentValues(tempMatrix);
    SetButtonColor(tempMatrix, 8);
    if (true)
    {
       await Task.Delay(2000);
       // ReturnButtonsDefaultColor();
    }
    ReturnButtonsDefaultColor();
       await Task.Delay(2000);

    tempMatrix = ResetTempMatrix(tempMatrix);
}

Use a Timer . Instead of your Thread.Sleep Start() the timer, in the tick event call ReturnButtonsDefaultColor(). You could use a second timer instead of the second Thread.Sleep or save some sort of state and use it in the tick event.

You can use Tasks:

        private void button10_Click(object sender, EventArgs e)
        {

            int[,] tempMatrix = new int[3, 3];
            tempMatrix = MakeMatrix();
            tempMatrix = SetDifferentValues(tempMatrix);
            SetButtonColor(tempMatrix, 8);

            Task.Factory.StartNew(
                () => 
                {
                    if (true)
                    {
                        Thread.Sleep(1000);
                        // ReturnButtonsDefaultColor();
                    }
                    ReturnButtonsDefaultColor(); //Need to dispatch that to the UI thread
                    Thread.Sleep(2000);

                    tempMatrix = ResetTempMatrix(tempMatrix); //Probably that as well
                });
        }

Dispatching in WPF is different from Winforms, it should be easy enough to google ;)

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