Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call Thread.Sleep from the Task

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.

like image 743
SerG Avatar asked Dec 16 '13 12:12

SerG


People also ask

How do you make a thread sleep?

Thread. sleep() method can be used to pause the execution of current thread for specified time in milliseconds. The argument value for milliseconds can't be negative, else it throws IllegalArgumentException .

Is Task delay better than thread sleep?

sleep will block a thread and task. delay will not and has a cancellation token, unless your app is pretty complex, it really doesn't matter as on the surface: task. delay and thread. sleep do pretty much the same thing.

What's thread sleep () in threading?

Suspends the current thread for the specified number of milliseconds. Suspends the current thread for the specified amount of time.

How do you call sleep in Java?

sleep() Method: Method Whenever Thread. sleep() functions to execute, it always pauses the current thread execution. If any other thread interrupts when the thread is sleeping, then InterruptedException will be thrown.


2 Answers

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.

like image 74
dcastro Avatar answered Oct 17 '22 17:10

dcastro


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.

like image 22
Panagiotis Kanavos Avatar answered Oct 17 '22 16:10

Panagiotis Kanavos