Hamma
Hamma

Reputation: 303

Backgroundworker and CPU usage

I need to do some background work every 20 seconds (it doesn't have to be exactly 20000ms, I can allow delays). I am using a Backgroundworker that executes the function and then wait another 20 seconds using a Timer:

private readonly BackgroundWorker Worker = new BackgroundWorker();
volatile bool keepWorkerRunning;

Worker.DoWork += Worker_DoWork;


    private void Worker_DoWork(object sender, DoWorkEventArgs e)
    {
        System.Timers.Timer aTimer = new System.Timers.Timer();
        aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
        aTimer.Interval = 20000;
        aTimer.Enabled = true;
        keepWorkerRunning = true;
        while (keepWorkerRunning) ;
        aTimer.Enabled = false;
    }

This worker is active for the whole time while the software is running.

The problem is that it takes most of the CPU. I noticed that my software is using around 70% of the CPU all the time, and just deactivating the Backgroundworker the CPU usage drops to 0.5%.

How can I do the same job without overloading the CPU?

Upvotes: 1

Views: 2789

Answers (1)

dymanoid
dymanoid

Reputation: 15197

The CPU is eaten by this loop:

while (keepWorkerRunning);

You effectively instruct the CPU to loop "doing nothing" as fast as possible. Hence 70% CPU load, it might be even worse (up to 100% depending on your CPU/cores).

Don't use BackgroundWorker at all. The Elapsed event is raised by the Timer on a thread pool thread (the SynchronizingObject property of the timer should be null), so it will run in background.

More information you can get here.


Update: As requested, here is a sample.

using System.Timers;

class MyClass : IDisposable
{
  readonly Timer aTimer = new Timer(20000);

  public void StartTimer()
  {
    this.aTimer.Elapsed += this.OnTimedEvent;
    this.aTimer.Enabled = true;
  }

  void OnTimedEvent(object source, ElapsedEventArgs e)
  {
    // do your background work here
  }
}

Upvotes: 2

Related Questions