The Thread constructor does not understand async delegates. You can read about this here:
The "proper" way to execute periodically some code depends on where you want to run your code. Do you have any reason to run it on a dedicated thread? Some components are thread-affine, and require to be manipulated by the same thread for the entirety of their existence. If you have this (not very common) requirement, you can use the Thread constructor without async/await:
var myThread = new Thread(() =>
{
while (true)
{
var delayTask = Task.Delay(1000);
CPU_Load();
delayTask.Wait();
}
});
myThread.IsBackground = true;
myThread.Start();
Notice how the Task.Delay task is created before the CPU-bound operation, and then waited afterwards. This way the interval between two subsequent invocations of the CPU_Load method will be constant. It will not depend on the duration of the call itself.
If you don't need a dedicated thread, you can do the work more economically by using reusable threads from the ThreadPool. Which is exactly what your current MyTask implementation does, with the Task.Run method inside. To start the task is as easy as invoking the asynchronous method:
var myTask = MyTask();
Now the task is running, and will continue running until the process terminates, or the CPU_Load invocation fails, whatever comes first.
Another way to implement the asynchronous MyTask method would be to wrap the whole loop in a Task.Run, instead of having the Task.Run inside the loop. Functionally and performance-wise is almost identical:
var myTask = Task.Run(async () =>
{
while (true)
{
var delayTask = Task.Delay(1000);
CPU_Load();
await delayTask;
}
});
I have omitted the ConfigureAwait(false) because it's not really needed in this case. The ThreadPool does not have a synchronization context that can be captured by the await.
You could also consider using a Timer to run periodically your work, but in my opinion the Task-based approach is superior. It's quite tricky to enforce a non-overlapping execution policy with constant interval using a Timer. Caveats:
- The
System.Timers.Timer class is not thread-safe.
- It allows overlapping invocations of the event handler.
- It swallows any exceptions thrown inside the handler.
- It is possible for the
Elapsed event to be raised after stopping the Timer with the Stop method.
- There is no easy way to stop the timer, and then wait for all running event handlers to complete.
- The class is disposable and needs to be disposed.