C#在SAME按钮单击事件中启动和停止线程

时间:2017-02-23 12:09:28

标签: c# multithreading winforms visual-studio-2010 .net-4.0

我正在使用C#,。Net4.0和Visual Studio 2010,当用户点击按钮时,我试图从我的Windows窗体应用程序中获取此行为:

  1. GUI LED开始闪烁
  2. 长梯级操作开始
  3. 当第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();
    }
    
  4. 我也尝试过使用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仍然无效。

    仅供参考:如果我按下一个开始闪烁的按钮,另一个按钮停止闪烁,它就能完美运行。

1 个答案:

答案 0 :(得分:1)

问题是,你正在占用Thread.Sleep内的UI线程。 UI线程是特殊的 - 它是唯一可以对UI进行更改的线程 - 因此当它忙于休眠时,它无法为您的BackgroundWorkerLED_Blink计时器回调中的任何尝试提供服务来更改UI状态。

所以,你需要不要绑定UI线程。您需要将Thread.Sleep代码(或它的实际等效代码)放入BackgroundWorker DoWork处理程序,或使用其他方法来避免阻止UI线程。

今天的常用方法是使用async / await,如果您尝试的实际工作已经提供了异步替代方案(例如await Task.Delay(2000);将等同于你当前的Thread.Sleep(2000);)。不幸的是,使用asyncawait会要求您转移到.NET / Visual Studio的更高版本 - 但无论如何您应该考虑这一点。 2010年已经过时了(而且,IMO,可能是最糟糕的一个 - 它出了名的很慢),并且不再支持.NET 4.0(而不是.NET 4.5.2或更高版本)。