2014-11-25 56 views
1

我有这个红绿灯程序,模拟了我住的地方附近的一个奇怪的十字路口。我很确定我有逻辑了。我有代表灯光各种可能状态的功能,包括黄灯。问题是我的黄灯都没有画。汽车熄灯五秒钟后,没有其他车辆通过绿灯,适当灯光的黄灯应打开三秒钟,然后变为绿灯。出于某种原因,当我浏览我的程序时,没有黄灯正在绘画。这里是我的代码:Thread.Sleep和绘画UI

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秒定时器正在工作,但是我画的光线不是。 (我画在其他功能就像我在这里做的,它工作正常)

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

+1

WaitThreeSecs() TOT强制权之前,我认为代码是从UI线程中调用?像直接关闭按钮点击? – BradleyDotNET 2014-11-25 01:32:54

+0

实际上,它听起来像是在UI线程上调用函数,所以你的假设是正确的。睡眠正在阻止UI线程更新屏幕。 – Wizetux 2014-11-25 01:35:40

+0

该函数是一个dispatchtimer事件处理程序。 那么我该如何去让线程更新屏幕,然后等待3秒? – bwighthunter 2014-11-25 01:39:44

回答

1

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

通过睡觉UI线程,您不用花时间来绘制屏幕。它切换颜色,然后返回,没有运行的绘画方法。

你最好的解决办法是使用一个标准Timer这样你就不会在UI线程上,然后用Dispatcher.BeginInvoke(WPF)或Control.Invoke(的WinForms)元帅更改到UI线程。您也可以消除Thread.Sleep并使更多定时器触发下一个更改。

-2

使用Application.DoEvents屏幕刷新

+1

虽然这解决了问题;它几乎是*从来没有正确的方法。使用它是一个巨大的代码气味,并有更好的方法。 – BradleyDotNET 2014-11-25 01:46:46

+0

是的,但这不是问题。 – 2014-11-25 01:49:10

+0

我必须添加“使用”才能做到这一点吗? – bwighthunter 2014-11-25 01:51:25