SyntaxHighlighter

Sunday 1 September 2013

Task Parallel Library equivalent of Thread.Sleep()

This post was originally on my Posterous account, it's posted here without updating, some of the links my not work.

Recently I had need to use Thread.Sleep() inside a TPL Task.  Thread.Sleep is usually something I avoid but I was testing out a theory and Sleep was my "long running process".  However I also needed this to scale to 50-60 tasks running in parallel, and Sleep was wasting an entire thread that could be better served doing real work.
So I needed a solution that would cause a Sleep task, that returned the thread back to the thread pool while it was sleeping.  Some searches on the net didn't find much but it turns out to be pretty easy.  Here is the solution I eventually settled on:
    public class TimerTask
    {
        public static Task Wait(int millisecondsToWait)
        {
            var tcs = new TaskCompletionSource<object>();
 
            var timer = new System.Threading.Timer(delegate(object obj)
                                                   {
                                                       tcs.SetResult(null);
                                                   },
                null, millisecondsToWait, System.Threading.Timeout.Infinite);
 
            Task<object> waitTask = tcs.Task;
            waitTask.ContinueWith(antecedant => timer.Dispose());
            return waitTask;
        }
    }
Hopefully someone else will find this useful.
Note: I think there might be an issue with Timer resources running out if a very large number of these are in use at the same time, but I havn't seen this in practise.

No comments: