简体   繁体   中英

Can I use Task.Delay as a timer?

I want to execute some code on each second. The code I am using now is:

Task.Run((Action)ExecuteSomething);

And ExecuteSomething() is defined as below:

 private void ExecuteSomething()
        {
            Task.Delay(1000).ContinueWith(
               t =>
               {
                   //Do something.

                   ExecuteSomething();
               });
        }

Does this method block a thread? Or should I use Timer class in C#? And it seems Timer also dedicates a separate thread for execution (?)

Task.Delay uses Timer internally

With Task.Delay you can make your code a little-bid clearer than with Timer . And using async-await will not block the current thread (UI usually).

public async Task ExecuteEverySecond(Action execute)
{
    while(true)
    {
        execute();
        await Task.Delay(1000);
    }
}

From source code: Task.Delay

// on line 5893
// ... and create our timer and make sure that it stays rooted.
if (millisecondsDelay != Timeout.Infinite) // no need to create the timer if it's an infinite timeout
{
    promise.Timer = new Timer(state => ((DelayPromise)state).Complete(), promise, millisecondsDelay, Timeout.Infinite);
    promise.Timer.KeepRootedWhileScheduled();
}

// ...

Microsoft's Reactive Framework is ideal for this. Just NuGet "System.Reactive" to get the bits. Then you can do this:

IDisposable subscription =
    Observable
        .Interval(TimeSpan.FromSeconds(1.0))
        .Subscribe(x => execute());

When you want to stop the subscription just call subscription.Dispose() . On top of this the Reactive Framework can offer far more power than Tasks or basic Timers.

static class Helper
{
    public async static Task ExecuteInterval(Action execute, int millisecond, IWorker worker)
    {
        while (worker.Worked)
        {
            execute();

            await Task.Delay(millisecond);
        }
    }
}


interface IWorker
{
    bool Worked { get; }
}

Can you use Task.Delay as a timer? It depends on whether you need to be waiting an exact interval, or whether you just need to wait a specified interval AFTER other work is done.

In other words, I have used a Timer many times in the past as part of a service that fetches or pushes data for the purposes of synchronization. The problem is that if you fetch data every 60 seconds, but there is a slow in the database and your retrieval takes over 60 seconds. Now you have a problem as you are going to be fetching the same data twice. So then you update the process so that you stop the timer until it finishes, and then start the timer again. This works fine, but using Task.Delay does this work for you.

So if you are just needing to Delay for a bit of time between executions, then Task.Delay works perfectly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM