Correct way to delay the start of a Task

.net, c#, task-parallel-library

Solution

Like Damien_The_Unbeliever mentioned, the Async CTP includes `Task.Delay`. Fortunately, we have Reflector:

public static class TaskEx
{
    static readonly Task _sPreCompletedTask = GetCompletedTask();
    static readonly Task _sPreCanceledTask = GetPreCanceledTask();

    public static Task Delay(int dueTimeMs, CancellationToken cancellationToken)
    {
        if (dueTimeMs < -1)
            throw new ArgumentOutOfRangeException("dueTimeMs", "Invalid due time");
        if (cancellationToken.IsCancellationRequested)
            return _sPreCanceledTask;
        if (dueTimeMs == 0)
            return _sPreCompletedTask;

        var tcs = new TaskCompletionSource<object>();
        var ctr = new CancellationTokenRegistration();
        var timer = new Timer(delegate(object self)
        {
            ctr.Dispose();
            ((Timer)self).Dispose();
            tcs.TrySetResult(null);
        });
        if (cancellationToken.CanBeCanceled)
            ctr = cancellationToken.Register(delegate
                                                 {
                                                     timer.Dispose();
                                                     tcs.TrySetCanceled();
                                                 });

        timer.Change(dueTimeMs, -1);
        return tcs.Task;
    }

    private static Task GetPreCanceledTask()
    {
        var source = new TaskCompletionSource<object>();
        source.TrySetCanceled();
        return source.Task;
    }

    private static Task GetCompletedTask()
    {
        var source = new TaskCompletionSource<object>();
        source.TrySetResult(null);
        return source.Task;
    }
}

Problem

I want to schedule a task to start in x ms and be able to cancel it before it starts (or just at the beginning of the task). The first attempt would be something like ``` var _cancelationTokenSource = new CancellationTokenSource(); var token = _cancelationTokenSource.Token; Task.Factory.StartNew(() => { token.ThrowIfCancellationRequested(); Thread.Sleep(100); token.ThrowIfCancellationRequested(); }).ContinueWith(t => { token.ThrowIfCancellationRequested(); DoWork(); token.ThrowIfCancellationRequested(); }, token); ``` But I feel like there should be a better way, as this would use up a thread while in the sleep, during which it could be canceled. What are my other options?

Original source