1

I have in my c# app backgroundworker and in dowork infinite loop but backgroundworker has very big cpu usage (50%). How to limit cpu usage of backgroundworker?

Code:

private void ScanWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        BackgroundWorker worker = sender as BackgroundWorker;

        while (!worker.CancellationPending)
        {
            Process[] Procesy = Process.GetProcesses();

            foreach (Process Proces in Procesy)
            {

                List<BlaclistedProcess> blacklist = (from p in CurrentBlacklist.Processes
                                                     where p.ProcessName == Proces.ProcessName
                                                     select p).ToList<BlaclistedProcess>();

                if (blacklist.Count == 1)
                {
                    Proces.Kill();
                }
            }
        }
    }
  • 2
    Can you show the code that is causing the issue ? – coolmine Mar 24 '13 at 15:56
  • I'd recommend only doing this based on a timer. Maybe once or twice a second... – Peter Ritchie Mar 24 '13 at 16:04
  • 1
    Don't poll, let Windows tell you when a [process starts](http://stackoverflow.com/questions/1986249/c-sharp-process-monitor). Do keep the fallacy in mind of this approach. If you have a black-list then just prevent these programs from starting in the first place. – Hans Passant Mar 24 '13 at 16:42

5 Answers5

1

Within the loop you could make the background thread wait a certain amount of time, e.g.

System.Threading.Thread.Sleep(100)
pbalaga
  • 2,018
  • 1
  • 21
  • 33
  • Thread.Sleep cause the thread to be "in use", waiting. Not the best use of a thread when resources like `Timer` are available. – Peter Ritchie Mar 24 '13 at 16:27
1

It would be easier to just use a timer and check periodic for those processes, no need to do that in another thread.

darthmaim
  • 4,970
  • 1
  • 27
  • 40
0

Based on your code you have a few options.

Personally I would use the Timer class instead of a BackgroundWorker since it's not necessary to do checks every few milliseconds like you are now.

Another alternative to avoid using Thread.Sleep() would be to use the Thread class so you will be able to set it's priority to lowest or below normal.

coolmine
  • 4,427
  • 2
  • 33
  • 45
0

Use a timer:

    var timer = new System.Threading.Timer(CheckProcesses);
    timer.Change(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1));
    //...
    timer.Dispose();

private void CheckProcesses(object state)
{
    Process[] Procesy = Process.GetProcesses();

    foreach (Process Proces in Procesy)
    {

        List<BlaclistedProcess> blacklist = (from p in CurrentBlacklist.Processes
                                             where p.ProcessName == Proces.ProcessName
                                             select p).ToList<BlaclistedProcess>();

        if (blacklist.Count == 1)
        {
            Proces.Kill();
        }
    }
}

With a timer you have better control over how often you perform the task. While the timer isn't running, not threads are in use--so it's more scalable. With Thread.Sleep() you have to devote a thread to "waiting"--which could impact how quickly the background worker can respond to cancellation and make your UI appear frozen.

Peter Ritchie
  • 35,463
  • 9
  • 80
  • 98
-1

Add Thread.Sleep(...) to the end of while cycle. That way there will be some small pause between checking processes, and cpu usage will drop significantly.

alex
  • 12,464
  • 3
  • 46
  • 67
  • Thread.Sleep causes the thread to be "in use", waiting. Not the best use of a thread when resources like `Timer` are available. – Peter Ritchie Mar 24 '13 at 16:27
  • Depends on how often does he want to check the processes. If he needs to check every 50 ms, and the check itself takes 100 ms, then timer would fire constantly and repeatedly, where Thread.Sleep will still introduce some pauses. – alex Mar 24 '13 at 16:32
  • If it's constant, then he needs to change the period... `Thread.Sleep` is not as accurate. It may be less than the ms you pass in, it may be less. i.e. you can't use Thread.Sleep() to check "every 50ms" – Peter Ritchie Mar 24 '13 at 16:34