Xaphann
Xaphann

Reputation: 3677

Performance issues with background process WPF

In my app I need a process that will work in the background and check for changes for various things. Then do some logic. Most of the time this process will be idle and just be waiting for the trigger point. So this is what I did:

private void MyBackgoroundThread()
{
    while (isRunning)
    {
        if (MyStatus == 1)
        {
            //Log removed
        }
    }
}

Then at run time it would be called by the constructor with the follow;

await Task.Run(() => MyBackgoroundThread());

Now this works perfectly. The problem now is that my app when idle uses about 35% CPU usage. Disabling the MyBackgoroundThread the app uses 0% CPU usage at idle. So I know it's this thread.

I understand why this is happening but my question is what is best practice for handling this situation so I don't burn 35% CPU for doing nothing.

Edit: based on comments;

@Dour High Arch Explain what “the trigger point” is

Basically the variable MyStatus is a global variable that when the process has to be "triggered" the status gets change to 1 for example. Sorry thought was clear in the code.

@Ron Beyer This seems dangerous given that the "background" task is an infinite loop, how is the await supposed to return?

Well you are at the meat of the issues. The global variable isRunning gets changed to false on the app closing. I am looking for a better solution

Upvotes: 0

Views: 207

Answers (1)

Eric J.
Eric J.

Reputation: 150208

You are using 1 CPU, more or less, to constantly iterate your while statement.

The best solution depends on what you are doing in that code. If at all possible, use an event or similar notification to trigger background work rather than a polling thread. For example if you're looking for changes to files, use a FileSystemWatcher.

If your code, rather than an external agent, is causing the need to do work, you can also consider a Producer/Consumer pattern. In that case, have a look at BlockingCollection, which makes implementing that pattern a snap.

If there is no way to use an event-based notification mechanism to trigger the background work, you can use Thread.Sleep() to at least have your polling thread sleep for a time, until it has to wake up and check for work again.

UPDATE based on your edits

basically the variable MyStatus is a global variable that when the process has to be "triggered" the status gets change to 1 for example. Sorry thought was clear in the code.

Change it from a global variable to a static property, and have it fire off an event when the value is changed. Instead of using your polling thread, have some code that subscribes to your new event.

The global variable isRunning gets changed to false on the app closing.

A background thread will automatically close when the application closes.

Upvotes: 3

Related Questions