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 (?)
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.
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();
}
// ...
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; }
}