简体   繁体   English

Thread.Sleep和绘画UI

[英]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. 五秒钟后将调用FromStateOneToTwo(),但是指示灯永远不会发黄。 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. 从按下按钮到适当的灯从红色直变为绿色,灯会等待8秒钟,这意味着我的3秒钟计时器正在工作,但我的绘画灯却没有工作。 (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. 您不会遇到跨线程InvalidOperation异常,因此我假设所提供的函数在UI线程上运行。 This will happen if you invoke it off of a button-click, or the elapsed event of a DispatcherTimer . 如果您是通过单击按钮或DispatcherTimer的已过去事件来调用它,则将发生这种情况。

By sleeping the UI thread, you don't give it time to paint the screen. 通过休眠UI线程,您不必花时间画屏幕。 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). 最好的解决方案是使用标准Timer这样您就不必进入UI线程,然后使用Dispatcher.BeginInvoke (WPF)或Control.Invoke (WinForms)将对UI线程的更改编组。 You can also eliminate Thread.Sleep and make more timers to trigger the next changes. 您还可以消除Thread.Sleep并增加计时器以触发下一个更改。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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