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.