.NET 6.0 PeriodicTimer in Background Thread 300% cpu

131 views Asked by At
var timer = new PeriodicTimer(TimeSpan.FromMinutes(5));

new Thread(async () =>
    {
        try
            {
                while (await timer.WaitForNextTickAsync().ConfigureAwait(false))
                {
                    ... do some things
                }
            }
            catch (OperationCanceledException)
            {
            }
    })
    {
        IsBackground = true,
    }
.Start();

Every 5 minutes I have to do some things in the background thread. For some reason in some random time I get 300% cpu usage. Something wrong with my code? Thanks.

1

There are 1 answers

0
Theodor Zoulias On

Something wrong with my code?

Yes, there is something wrong with this code, but fixing it will not solve the CPU over-utilization problem. The wrong thing is that you pass an asynchronous delegate to the Thread constructor. The Thread class does not expect an async delegate in the constructor, so the delegate is async void, which is something to avoid. You can learn why this is pointless from the answer in this question:

You can fix this by replacing the new Thread(async () => with Task.Run(async () =>. The Task.Run method understands async delegates, and will give you back a Task that you can later await, or query for its completion and potential Exception. In case you want to keep the existing async void semantics, meaning that in case of an unhandled exception you want your program to crash, then replace the new Thread(async () => with ThreadPool.QueueUserWorkItem(async _ =>.

As for the reason for the CPU spikes, it is hidden in the ... do some things code. We don't know what this code does, so we can't help you fix it.