我正在使用C#,。Net4.0和Visual Studio 2010,当用户点击按钮时,我试图从我的Windows窗体应用程序中获取此行为:
当第2点的操作结束时,LED停止闪烁
private void Btn_WebService_Click(object sender, EventArgs e)
{
Thread_Blink = new Thread(() => { LED_Blink(LED.WS); });
Thread_Blink.Start();
// Do something that takes time.. Let's imulate with a sleep
Thread.Sleep(2000);
Thread_Blink.Abort();
}
我也尝试过使用3种不同的事件和/或计时器。
private void Btn_WebService_MouseDown(object sender, MouseEventArgs e)
{
Timer_Blink.Enabled = true;
}
private void Btn_WebService_Click(object sender, EventArgs e)
{
// Do something that takes time.. Let's imulate with a sleep
Thread.Sleep(2000);
}
private void Btn_WebService_MouseUp(object sender, MouseEventArgs e)
{
Timer_Blink.Enabled = false;
}
结果始终相同:LED仅在长时间运行(Thread.Sleep(2000);
)的结束时开始闪烁并突然停止,以便您无法看到任何内容。为什么会发生这种情况?如何才能获得所需的行为?
我添加更多信息。我尝试使用BackgroundWorked并以这种方式实现了所需的行为:
private void Btn_WebService_Click(object sender, EventArgs e)
{
BlinkWorker.RunWorkerAsync(LED.WS);
LedOn(LED.WS);
TestWebService(); // This method takes about 2 seconds to answer..
LedOff(LED.WS);
BlinkWorker.CancelAsync();
}
当TestWebService()运行时,我关闭了LED(LedOn(LED.WS);)。当TestWebService()完成后,LED亮起。 如果在Click事件中启动和取消,BlinkWorker仍然无效。
仅供参考:如果我按下一个开始闪烁的按钮,另一个按钮停止闪烁,它就能完美运行。
答案 0 :(得分:1)
问题是,你正在占用Thread.Sleep
内的UI线程。 UI线程是特殊的 - 它是唯一可以对UI进行更改的线程 - 因此当它忙于休眠时,它无法为您的BackgroundWorker
或LED_Blink
计时器回调中的任何尝试提供服务来更改UI状态。
所以,你需要不要绑定UI线程。您需要将Thread.Sleep
代码(或它的实际等效代码)放入BackgroundWorker
DoWork
处理程序,或使用其他方法来避免阻止UI线程。
今天的常用方法是使用async
/ await
,如果您尝试的实际工作已经提供了异步替代方案(例如await Task.Delay(2000);
将等同于你当前的Thread.Sleep(2000);
)。不幸的是,使用async
和await
会要求您转移到.NET / Visual Studio的更高版本 - 但无论如何您应该考虑这一点。 2010年已经过时了(而且,IMO,可能是最糟糕的一个 - 它出了名的很慢),并且不再支持.NET 4.0(而不是.NET 4.5.2或更高版本)。