Thread.Sleep和绘画UI

时间:2014-11-25 01:30:56

标签: c# multithreading

我有这个红绿灯计划,模拟我住的地方附近的一个奇怪的交叉路口。我很确定我的逻辑是正确的。我有功能代表灯的每个可能状态,包括黄色。问题是我的黄灯都没有画画。汽车拉到一盏灯后五秒钟没有其他汽车通过绿灯,适当灯光的黄灯应亮三秒钟,然后变为绿灯。出于某种原因,当我单步执行我的程序时,没有黄灯在画画。这是我的代码:

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(),但灯不会变黄。我不知道为什么这不会发生。从按下按钮到适当的光线直接从红色变为绿色时,灯光会等待8秒钟,这意味着我的3秒定时器正在工作,但我的绘画灯光却没有。 (我在其他功能中绘制的方式与我在这里完全一样,并且工作正常)

如果需要,我可以显示更多/所有代码。

2 个答案:

答案 0 :(得分:1)

您没有获得跨线程InvalidOperation异常,因此我假设提供的函数在UI线程上运行。如果您通过按钮单击或DispatcherTimer已过去的事件调用它,就会发生这种情况。

通过休眠UI线程,您没有给它时间绘制屏幕。它会切换颜色,然后返回,而不会使用绘制方法。

您最好的解决方案是使用标准Timer,因此您不在UI线程上,然后使用Dispatcher.BeginInvoke(WPF)或Control.Invoke将您对更改的UI线程进行封送(的WinForms)。您还可以消除Thread.Sleep并生成更多计时器以触发下一次更改。

答案 1 :(得分:-2)

Application.DoEvents强制屏幕刷新

之前使用WaitThreeSecs()