2017-09-01 4 views
1

Je pensais au début que ce serait juste une question "How to wait for async method to complete?". Mais, je pense que c'est un peu plus que ça.Empêche le redémarrage d'une minuterie jusqu'à ce que sa tâche asynchrone soit terminée

J'ai une minuterie mis en place en tant que telle ...

public void Start() 
{ 
    _timer.Elapsed += new ElapsedEventHandler(timer_Elapsed); 
    _timer.Interval = _context.adpSettings.SyncInterval * 1000; 
    _timer.AutoReset = false; 
    _timer.Enabled = true; 
} 

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    var t = ExecuteTransactionReportAsync(); 
    _timer.Start(); 
} 

private async Task ExecuteTransactionReportAsync() 
{ 
    AccessEvent accessEvent = new AccessEvent(); 
    .... do some logic 
    await _context.GetConnector().EnqeueuEventAsync(accessEvent); 
} 

Ce que je suis en train de faire est de ne pas avoir timer_Elapsed() le feu à nouveau qu'après ExecuteTransactionReportAsync() se fait. Mais, parce que ExecuteTransactionReportAsync() est asynchrone, le processus continue et timer_Elapsed() tirera à nouveau.

Dans la vraie vie, il ne faudra jamais ExecuteTransactionReportAsync() plus de 10 secondes pour terminer sa tâche. (Au moins, il vaut mieux ne pas ou nous avons d'autres problèmes.) Mais quand je débogue, c'est une douleur.

Existe-t-il une solution simple qui n'implique pas de rendre ExecuteTransactionReportAsync() non asynchrone?

+1

Arrêtez la minuterie, exécutez la tâche async, ajoutez 'ContinueWith 'à la tâche de redémarrer le minuteur? – DavidG

+1

N'utilisez pas de minuterie, mais plutôt un seul fil avec une boucle avec un retard à la fin de la boucle. – Sinatr

+1

'var t = await ExecuteTransactionReportAsync();'? Vous devez rendre l'eventHandler async pour l'utiliser. – Fildor

Répondre

1

Si ma compréhension de la TAP est correcte, alors cela devrait fonctionner comme prévu:

private async void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    await ExecuteTransactionReportAsync(); 
    _timer.Start(); 
} 

Ou ce Davidg suggérait:

private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    _timer.Stop(); 
    ExecuteTransactionReportAsync().ContinueWith(() => {_timer.Start(); }); 
} 
+0

Ça marche! Je pensais que j'avais essayé, mais je suppose que non. Merci! –

+0

Ok, dans mon premier commentaire quand j'ai dit "ça marche" je parlais de ton premier exemple. Votre deuxième exemple est plus ce à quoi je pensais ou que je cherchais. Mais j'aime mieux ton premier exemple. –