简体   繁体   中英

C# Start and Stop Thread inside SAME button click event

I am using C#,.Net4.0 and Visual Studio 2010 and I am trying to get this behaviour from my windows form application when the user click on a button:

  1. A GUI LED starts to blink
  2. A long rung operation starts
  3. When the operation at point 2 ends the LED stops blinking

     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(); } 

I also tried using 3 different events and/or timers..

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;
}

The result is always the same: The LED starts to blink only AT THE END of the long running operation ( Thread.Sleep(2000); ) and suddenly STOPS so that you can't see anything. Why does this happen and how can I get the desired behaviour?

I add further infos. I tried to use BackgroundWorked and implemented the wanted behavour in this way:

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();
    }

While the TestWebService() is running I get the LED off(LedOn(LED.WS);). When the TestWebService()has finished the LED comes on. The BlinkWorker still does not work if started and cancelled inside the Click event.

FYI: If I make a button that starts the blinking and another button that stops it, it works perfectly.

The problem is, you're tying up the UI thread inside that Thread.Sleep . The UI thread is special - it's the only one that can make changes to the UI - so whilst it's busy sleeping, it's not able to service any attempts from your BackgroundWorker or LED_Blink timer callback to change the UI state.

So, you need to not tie up the UI thread. You need to put the Thread.Sleep code (or it's actual real equivalent) into the BackgroundWorker s DoWork handler, or use other means to avoid blocking the UI thread.

Common approaches today would be to make use of async / await if the real work you're trying to do already offers an asynchronous alternative (eg await Task.Delay(2000); would be the equivalent of your current Thread.Sleep(2000); ). Unfortunately, using async and await would require you to move to a later version of .NET/Visual Studio - but you ought to be considering that anyway. 2010 is quite dated (and also, IMO, probably the worst one to stop on - it was notoriously slow), and .NET 4.0 (as opposed to .NET 4.5.2 or later) is no longer supported.

我建议您看一下BackgroundWorker类和ReportProgress方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM