Как я могу поддержать отмену долго выполняющейся задачи потребителя masstransit, когда служба Windows, содержащая верхнюю полку, остановлена
Я использую сервис Windows верхнего уровня для размещения потребителя сообщений masstransit. Одна из задач потребителя может занять до 30 минут, но ее легко прервать и перезапустить. Когда я вручную останавливаю службу, я хотел бы, чтобы задача потребителя была корректно остановлена как можно скорее и чтобы masstransit возвращал сообщение в очередь, откуда оно пришло.
Теперь у меня есть это работает с CancellationToken
что вызывает долгосрочную задачу, чтобы бросить TaskCanceledException
, В конфигурации шины я использую конфигурацию повтора, чтобы дождаться, пока процесс не будет окончательно завершен, и, таким образом, вернуть сообщение в очередь. Есть ли лучший способ реализовать это? Теперь я получаю исключение, зарегистрированное массовым транспортом, и моя служба не останавливается так быстро, как следовало бы, потому что она ждет Thread.Sleep
,
В долгосрочной перспективе потребитель
if (this.cancellationToken.IsCancellationRequested)
{
throw new TaskCanceledException("manual cancel");
}
Код повтора в конфигурации шины
var busControl = Bus.Factory.CreateUsingRabbitMq(sbc =>
{
sbc.UseRetry(x =>
{
x.Intervals(this.busConfiguration.RetryIntervals);
x.Ignore<Exception>(ex =>
{
if (cancellationTokenSource.IsCancellationRequested)
{
this.loggingService.LogWarning("Worker stopped manually, messages in progress have been returned to the queue.");
// Wait for process to end, this is not great because this causes mass transit to log an error
Thread.Sleep(TimeSpan.FromDays(1));
}
return false;
});
});
}
Когда служба остановлена
public virtual void Stop()
{
this.cancellationTokenSource.Cancel();
this.busHandle.Stop();
}