Search code examples
c#multithreadingbackgroundworkerbackground-processinvoke

BackgroundWorker update elapsed time label using stopwatch, freeze due to invoke C#


I'm Trying to create a Live Stopwatch which is running in a background worker inside a user control and I'm updating the label which is the elapsed time in the UI using Invoke Method it works fine when 2 background workers are running simultaneously.

i noticed that the problem is that I'm trying to invoke the label each second and that is multiplied by the number of the user controls i create so it freezes i tried to comment the invoke method it just worked fine but i couldn't update the label with the elapsed time without invoke method.

public void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
     Stopwatch stopWatch = new Stopwatch();
     stopWatch.Start();
     while (!backgroundWorker1.CancellationPending)
     {
         TimeSpan ts = stopWatch.Elapsed;
         string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}", ts.Hours,ts.Minutes, ts.Seconds);               
         label2.Invoke((MethodInvoker)delegate
         {
             label2.Text = elapsedTime;
         });
     }
     stopWatch.Stop();
}

this is an image for the generated user controls that uses stopwatches https://i.sstatic.net/mAQLP.png .

how could i update the label with the elapsed time without the application freezes considering that i may have more than one user control running simultaneously.


Solution

  • I figured out the Timer should be used instead of Background worker which can be used for such problems.

    Stopwatch sw = new Stopwatch();
    
    private void timer1_Tick(object sender, EventArgs e)
    {
        long h = sw.Elapsed.Hours;
        long m = sw.Elapsed.Minutes;
        long s = sw.Elapsed.Seconds;
        long t = sw.Elapsed.Ticks;
    
        string strH = (h < 10) ? "0" + h : h + "";
        string strM = (m < 10) ? "0" + m : m + "";
        string strS = (s < 10) ? "0" + s : s + "";
        string AllTime = strH + ":" + strM +":"+ strS;
    
        label2.Text = AllTime;
    }```