web-dev-qa-db-fra.com

Puis-je utiliser Task.Delay comme une minuterie?

Je veux exécuter du code à chaque seconde. Le code que j'utilise maintenant est:

Task.Run ((Action) ExecuteSomething);

EtExecuteSomething()est défini comme suit:

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

                   ExecuteSomething();
               });
        }

Est-ce que cette méthode bloque un thread? Ou devrais-je utiliser Timer class en C #? Et il semble Timer dédie également un fil séparé pour l'exécution (?)

11
Sharun

Le cadre réactif de Microsoft est idéal pour cela. Juste NuGet "System.Reactive" pour obtenir les bits. Ensuite, vous pouvez faire ceci:

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

Lorsque vous souhaitez arrêter l'abonnement, appelez simplement subscription.Dispose(). De plus, le cadre réactif peut offrir beaucoup plus de puissance que les tâches ou les minuteries de base.

4
Enigmativity

Task.Delay utilise Timer en interne

Avec Task.Delay, vous pouvez rendre votre code plus clair que avec Timer. Et utiliser async-await ne bloquera pas le thread actuel (l'interface utilisateur en général).

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

À partir du code source: 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();
}

// ...
14
Fabio
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; }
}
0
nim