2015-01-27 15 views
5

E 'possibile (o anche ragionevole) rendere la callback di un metodo asincrono System.Timers.Timer? Qualcosa di simile:Il callback Elapsed di un System.Timers.Timer può essere asincrono?

var timer = new System.Timers.Timer 
{ 
    Interval = TimeSpan.FromSeconds(30).TotalMilliseconds, 
    AutoReset = true 
}; 
timer.Elapsed += async (sender, e) => { /* await something */ }; 
timer.Start(); 

Si compila (ovviamente un buon punto di partenza), ma non sono sicuro di capire le conseguenze. Il timer sarà await la richiamata prima di resettare il timer?

risposta

15

Il timer await effettua la richiamata prima di reimpostare il timer?

No. Non c'è niente che potesse attendere, perché la firma di ElapsedEventHandler ha un tipo di ritorno vuoto.

In altre parole, il codice è equivalente a:

var timer = new System.Timers.Timer { ... }; 
timer.Elapsed += Foo; 
timer.Start(); 

... 
private async void Foo() 
{ 
    ... 
} 

Se questo è accettabile per voi o no dipenderà dal vostro contesto. In generale, disporre di metodi asincroni del vuoto o di funzioni anonime rende più difficile il test e il riutilizzo, ma l'abilità è stata data precisamente per il bene dei gestori di eventi ... Dovresti considerare come verranno propagati gli errori.

1

Il titolo della domanda riguarda specificamente Timer, ma se consideriamo "Come chiamare un metodo asincrono dopo un po 'di tempo?" allora potresti farlo senza usare un timer.

var task2 = Task.Run(async() => { 
    while (true) 
    { 
     try 
     { 
      await MyMethod2(); 
     } catch 
     { 
      //super easy error handling 
     } 
     await Task.Delay(TimeSpan.FromSeconds(5)); 
    } 
}); 

... 

public async Task MyMethod2() 
{ 
    //async work here 
} 

Si noti tuttavia che ciò avrà tempistica diversa (timer sarà chiamato ad intervalli, il codice precedente verrà chiamato ogni (time + sleep_time esecuzione), ma anche se MyMethod2 richiede molto tempo ha vinto Si può chiamare due volte. Detto questo, è possibile calcolare il tempo di attesa per eseguire "ogni x minuti".

Problemi correlati