简体   繁体   中英

Thread.Sleep and Painting UI

I have this stoplight program that models a strange intersection near where I live. I am pretty sure I have the logic down. I have functions that represent every possible state of the lights, including yellows. The problem is that none of my yellow lights are painting. Five seconds after a car pulls up to a light and no other cars have passed through green lights, yellow lights for appropriate lights are supposed to turn on for three seconds, and then turn green. For some reason when I step through my program, no yellow lights are painting. Here is my code:

private void WaitThreeSecs()
    {
        //somehow I think this is to blame
        int threeSeconds = 3000;
        Thread.Sleep(threeSeconds);
    }

    private void FromStateOneToTwo()
    {
        //Stop Countdown Timers
        fiveSec.Stop();
        thirtySec.Stop();

        //Indicate Current State
        CurrentState = 2;

        //Paint lights
        BottomGreen.Fill = gray;
        BottomYellow.Fill = yellow; // this never happens
        BottomRed.Fill = gray;

        //Wait 3 secs
        WaitThreeSecs();

        btnbottom.Content = "Car Stops";

        //Call function that changes the state for other lights to be green
        StateTwo();
    }

FromStateOneToTwo() is called after the five seconds, but the light is never yellow. I have no idea why this doesn't happen. The light waits 8 seconds from when a button is pressed to when the appropriate light goes straight from red to green, meaning that my 3 second timer is working, but my painting the light is not. (I paint in other function exactly like i do here, and it works fine)

I can show more/all of my code if needed.

You aren't getting a cross-thread InvalidOperation exception, so I'll assume that the provided function runs on the UI thread. This will happen if you invoke it off of a button-click, or the elapsed event of a DispatcherTimer .

By sleeping the UI thread, you don't give it time to paint the screen. It switches colors, then back, without a paint method ever running.

Your best solution is to use a standard Timer so you aren't on the UI thread, then marshal your changes to the UI thread with Dispatcher.BeginInvoke (WPF) or Control.Invoke (WinForms). You can also eliminate Thread.Sleep and make more timers to trigger the next changes.

WaitThreeSecs()强制刷新屏幕之前使用Application.DoEvents

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