Vorrei eseguire un Task che ha un "heartbeat" che continua a essere eseguito in un intervallo di tempo specifico fino al completamento dell'attività.Creazione di un'attività con heartbeat
Sto pensando un metodo di estensione come questo dovrebbe funzionare bene:
public static async Task WithHeartbeat(this Task primaryTask, TimeSpan heartbeatInterval, Action<CancellationToken> heartbeatAction, CancellationToken cancellationToken)
Ad esempio:
public class Program {
public static void Main() {
var cancelTokenSource = new CancellationTokenSource();
var cancelToken = cancelTokenSource.Token;
var longRunningTask = Task.Factory.StartNew(SomeLongRunningTask, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Current);
var withHeartbeatTask = longRunningTask.WithHeartbeat(TimeSpan.FromSeconds(1), PerformHeartbeat, cancelToken);
withHeartbeatTask.Wait();
Console.WriteLine("Long running task completed!");
Console.ReadLine()
}
private static void SomeLongRunningTask() {
Console.WriteLine("Starting long task");
Thread.Sleep(TimeSpan.FromSeconds(9.5));
}
private static int _heartbeatCount = 0;
private static void PerformHeartbeat(CancellationToken cancellationToken) {
Console.WriteLine("Heartbeat {0}", ++_heartbeatCount);
}
}
Questo programma dovrebbe uscita:
Starting long task
Heartbeat 1
Heartbeat 2
Heartbeat 3
Heartbeat 4
Heartbeat 5
Heartbeat 6
Heartbeat 7
Heartbeat 8
Heartbeat 9
Long running task completed!
Nota che non dovrebbe (in circostanze normali) output "Heartbeat 10" poiché l'heartbeat inizia dopo il timeout iniziale (es. 1 secondo). Allo stesso modo, se l'attività richiede meno tempo dell'intervallo di battito cardiaco, il battito cardiaco non dovrebbe verificarsi affatto.
cosa è un buon modo per implementare questo?
Informazioni di base: Ho un servizio che sta ascoltando una coda Azure Service Bus. Mi piacerebbe non Complete il messaggio (che eliminerebbe definitivamente dalla coda) fino a quando avrò finito di elaborarlo, che potrebbe richiedere più tempo rispetto al messaggio massima LockDuration di 5 minuti. Così, ho bisogno di usare questo approccio battito cardiaco per chiamare RenewLockAsync prima che la durata di blocco scade in modo che il messaggio non timeout mentre lungo l'elaborazione è in corso.
Questo suona simile a comunicare i progressi in un task asincrona (basta che la cosa innescando un rapporto è un intervallo di tempo, e non c'è un reale progresso per segnalare, ad eccezione forse conta il battito cardiaco). È utile uno di questi link? http://blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx http: // stackoverflow .com/questions/15408148/c-sharp-async-await-progress-event-on-task-object –
@TimS. Sono simili ma non proprio quello che voglio, specialmente con il caso di non riportare mai se l'attività si completa rapidamente. Inoltre, il battito cardiaco non conosce il progresso per dire. Tuttavia, sarei felice di vedere se è possibile implementare l'approccio progress per abbinare la mia API di estensione e avere lo stesso effetto netto con un codice più semplice. –