我正在使用topshelf 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();
}