Question

Is it correct to use Thread.Sleep() inside the task. Or is only a timer (Task.Delay() in .Net 4.5 and latter) used with task? Or maybe another approaches exist.

Was it helpful?

Solution

You can use Thread.Sleep inside a task. But in most situations I'd prefer to use await Task.Delay which does not block the thread.

If you're using Task.Run (which uses a ThreadPool thread), then you should try not to block the thread. As it is a shared thread, there may be other code waiting to run.

I would still use Thread.Sleep(0) when I'm done using the thread, to yield the processor and give up your time slice.

OTHER TIPS

It seems the real question is how to achieve the same effect as .NET 4.5's Task.Delay in .NET 4.0.

First, if you use Visual Studio 2012+ you can add the Microsoft.Bcl.Async nuget package to your project to enable async/await and other new functionality like Task.Delay. This is the most convenient method.

If you are using Visual Studio 2010, you can achieve the same results by creating a TaskCompletionSource that completes when a timer expires. This is already provided by the ParallelExtensionsExtras library as a set of extension methods.

The basic function is StartNewDelayed and there are many convenience overloads:

    /// <summary>Creates a Task that will complete after the specified delay.</summary>
    /// <param name="factory">The TaskFactory.</param>
    /// <param name="millisecondsDelay">The delay after which the Task should transition to RanToCompletion.</param>
    /// <param name="cancellationToken">The cancellation token that can be used to cancel the timed task.</param>
    /// <returns>A Task that will be completed after the specified duration and that's cancelable with the specified token.</returns>
    public static Task StartNewDelayed(this TaskFactory factory, int millisecondsDelay, CancellationToken cancellationToken)
    {
        // Validate arguments
        if (factory == null) throw new ArgumentNullException("factory");
        if (millisecondsDelay < 0) throw new ArgumentOutOfRangeException("millisecondsDelay");

        // Check for a pre-canceled token
        if (cancellationToken.IsCancellationRequested)
            return factory.FromCancellation(cancellationToken);

        // Create the timed task
        var tcs = new TaskCompletionSource<object>(factory.CreationOptions);
        var ctr = default(CancellationTokenRegistration);

        // Create the timer but don't start it yet.  If we start it now,
        // it might fire before ctr has been set to the right registration.
        var timer = new Timer(self =>
        {
            // Clean up both the cancellation token and the timer, and try to transition to completed
            try
            {
                ctr.Dispose();
            }
            catch (NullReferenceException)
            {
                // Eat this. Mono throws a NullReferenceException when constructed with
                // default(CancellationTokenRegistration);
            }

            ((Timer)self).Dispose();
            tcs.TrySetResult(null);
        });

        // Register with the cancellation token.
        if (cancellationToken.CanBeCanceled)
        {
            // When cancellation occurs, cancel the timer and try to transition to canceled.
            // There could be a race, but it's benign.
            ctr = cancellationToken.Register(() =>
            {
                timer.Dispose();
                tcs.TrySetCanceled();
            });
        }

        // Start the timer and hand back the task...
        try { timer.Change(millisecondsDelay, Timeout.Infinite); }
        catch(ObjectDisposedException) {} // in case there's a race with cancellation; this is benign

        return tcs.Task;
    }

Most of the code deals with properly disposing of the timer and handling cancellations.

In .NET 4.5 you should use Task.Delay. In .NET 4.0, since it doesn't have Task.Delay and Thread.Sleep inside a Task is a bad practice... create a custom task, and use a timer to mark ti as completed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top