Я хотел бы запустить Task, который имеет «heartbeat», который продолжает работать с определенным интервалом времени, пока задача не завершится.Создание задачи с биением
Я думаю, метод расширения, как это будет хорошо работать:
public static async Task WithHeartbeat(this Task primaryTask, TimeSpan heartbeatInterval, Action<CancellationToken> heartbeatAction, CancellationToken cancellationToken)
Например:
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);
}
}
Эта программа должна вывести:
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!
Обратите внимание, что (при нормальных обстоятельствах) не должно выводиться «Heartbeat 10», поскольку сердцебиение начинается после первоначального тайм-аута (т. 1 секунда). Аналогично, если задача занимает меньше времени, чем интервал сердцебиения, сердцебиение не должно происходить вообще.
Что такое хороший способ реализовать это?
Справочная информация: У меня есть служба, которая слушает очередь Azure Service Bus. Я бы хотел, чтобы сообщение Complete (которое навсегда удалило бы его из очереди), пока я не закончу его обработку, что может занять больше времени, чем максимальное сообщение LockDuration 5 минут. Таким образом, мне нужно использовать этот подход, чтобы позвонить RenewLockAsync до истечения времени блокировки, чтобы сообщение не перегревалось во время длительной обработки.
Это созвучно отчетность о проделанной работе в задаче асинхронной (только что вещь, запускающее отчет является интервалом времени, и нет никакого реального прогресса в докладе, за исключением возможно, подсчет пульса). Помогает ли любая из этих ссылок? 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/вопросы/15408148/c-sharp-async-wait-progress-event-on-task-object –
@TimS. Они похожи, но не совсем то, что я хочу, особенно в случае никогда не сообщать, быстро ли завершена задача. Кроме того, сердцебиение не знает прогресса в расчете. Тем не менее, я был бы рад узнать, можете ли вы реализовать подход прогресса, чтобы соответствовать моему API расширения и иметь тот же чистый эффект с более простым кодом. –