I'm new to .Net 4.0's Tasks and I wasn't able to find what I thought would be a Task based replacement or implementation of a Timer, e.g. a periodic Task. Is there such a thing?
Update I came up with what I think is a solution to my needs which is to wrap the "Timer" functionality inside a Task with child Tasks all taking advantage of the CancellationToken and returns the Task to be able to participate in further Task steps.
public static Task StartPeriodicTask(Action action, int intervalInMilliseconds, int delayInMilliseconds, CancellationToken cancelToken) { Action wrapperAction = () => { if (cancelToken.IsCancellationRequested) { return; } action(); }; Action mainAction = () => { TaskCreationOptions attachedToParent = TaskCreationOptions.AttachedToParent; if (cancelToken.IsCancellationRequested) { return; } if (delayInMilliseconds > 0) Thread.Sleep(delayInMilliseconds); while (true) { if (cancelToken.IsCancellationRequested) { break; } Task.Factory.StartNew(wrapperAction, cancelToken, attachedToParent, TaskScheduler.Current); if (cancelToken.IsCancellationRequested || intervalInMilliseconds == Timeout.Infinite) { break; } Thread.Sleep(intervalInMilliseconds); } }; return Task.Factory.StartNew(mainAction, cancelToken); }
It is always advised to use tasks instead of thread as it is created on the thread pool which has already system created threads to improve the performance. The task can return a result. There is no direct mechanism to return the result from a thread. Task supports cancellation through the use of cancellation tokens.
The main purpose of Task. Run() is to execute CPU-bound code in an asynchronous way. It does this by pulling a thread from the thread pool to run the method and returning a Task to represent the completion of the method.
Delay() doesn't block any thread, and if you want I can easily prove it. Patrick here is a proof that the await task. Delay() doesn't block a thread.
Differences Between Task And ThreadThe Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. The task can return a result.
It depends on 4.5, but this works.
public class PeriodicTask { public static async Task Run(Action action, TimeSpan period, CancellationToken cancellationToken) { while(!cancellationToken.IsCancellationRequested) { await Task.Delay(period, cancellationToken); if (!cancellationToken.IsCancellationRequested) action(); } } public static Task Run(Action action, TimeSpan period) { return Run(action, period, CancellationToken.None); } }
Obviously you could add a generic version that takes arguments as well. This is actually similar to other suggested approaches since under the hood Task.Delay is using a timer expiration as a task completion source.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With