2017-02-14 81 views
7

Chcę wykonać kod na sekundę. Kod, którego teraz używam, to:Czy mogę używać Task.Delay jako timera?

Task.Run ((Action) ExecuteCoś);

I ExecuteSomething() jest zdefiniowana jak poniżej:

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

        ExecuteSomething(); 
       }); 
     } 

Czy ta metoda blokowania wątku? Czy powinienem użyć klasy Timer w języku C#? I wydaje Timer also dedicates a separate thread for execution (?)

+1

Jeśli chodzi o "oddzielny wątek", istnieje tylko jeden wątek, który jest wspólny dla wszystkich timerów. –

Odpowiedz

5

Reactive Framework Microsoftu jest idealny do tego. Wystarczy NuGet "System.Reactive", aby uzyskać bity. Następnie można to zrobić:

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

Kiedy chcesz się zatrzymać subskrypcję zadzwoń subscription.Dispose(). Oprócz tego Reactive Framework może zaoferować znacznie więcej mocy niż Tasks lub Basic Timers.

+1

Czy używanie Rx w moim przypadku ma jakieś szczególne zalety niż używanie Task.Delay? Po prostu chcesz wiedzieć, czy warto dołączyć pakiet tylko w tym celu. Przegłosowane mimo to. – Sharun

+0

@Sharun - Rx ma tyle mocy, co LINQ, a potem kilka. Z tego, co opisałeś, nie ma już niczego, czego potrzebujesz, ale podejrzewam, że faktycznie skorzystasz z tego, co oferuje Rx. Czy możesz opisać więcej na temat tego, co próbujesz zrobić? – Enigmativity

9

Task.Delay wykorzystuje Timer wewnętrznie

Z Task.Delay można dokonać kod mało bid jaśniejsze następnie Timer. I używanie async-await nie będzie blokować bieżącego wątku (zazwyczaj UI).

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

z kodu źródłowego: 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(); 
} 

// ...