【问题标题】:C# Start and Stop Thread inside SAME button click eventC# 在 SAME 按钮单击事件中启动和停止线程
【发布时间】:2017-07-13 21:54:42
【问题描述】:

我正在使用 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();
    }
    

我还尝试使用 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 仍然无法工作。

仅供参考:如果我制作一个开始闪烁的按钮和一个停止闪烁的按钮,它就可以完美地工作。

【问题讨论】:

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


    【解决方案1】:

    问题是,您将 UI 线程绑定在 Thread.Sleep 中。 UI 线程很特殊 - 它是唯一可以更改 UI 的线程 - 因此,当它忙于睡眠时,它无法为您的 BackgroundWorkerLED_Blink 计时器回调提供任何尝试以更改 UI 状态。

    因此,您无需占用 UI 线程。您需要将 Thread.Sleep 代码(或它的实际等效代码)放入 BackgroundWorkers DoWork 处理程序中,或使用其他方式避免阻塞 UI 线程。

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

    【讨论】:

      【解决方案2】:

      我建议你看看 BackgroundWorker 类和 ReportProgress 方法。

      【讨论】:

        猜你喜欢
        • 2014-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-11
        • 2012-12-06
        • 2021-05-07
        • 1970-01-01
        相关资源
        最近更新 更多