【发布时间】:2017-12-25 09:09:41
【问题描述】:
我有一个在 RunAsync 方法中运行后台进程的无状态服务。
这个后台进程必须永远运行。它的作用无关紧要,但它实际上每 60 秒轮询一次数据库。
与辅助角色或 WebJob 不同,Service Fabric 服务中的 RunAsync 方法可以运行到完成,并且服务实例将保持正常运行。
当 Service Fabric 发出传递给 RunAsync 的取消令牌信号时,观察到会发生这种情况。
Service Fabric 决定从 RunAsync 方法正常返回后,如何再次重新运行轮询例程?
我如何才能确定 Service Fabric 首先发出取消令牌的原因?
我当前的解决方法是抛出异常,以便强制重新启动服务。
public class Stateless1 : StatelessService
{
protected override async Task RunAsync(CancellationToken cancellationToken)
{
try
{
await Start(cancellationToken);
}
catch(OperationCanceledException ex)
{
throw;
//If an OperationCanceledException escapes from
//RunAsync(CancellationToken) and Service Fabric runtime has requested
//cancellation by signaling cancellationToken passed to
//RunAsync(CancellationToken), Service Fabric runtime handles this exception and
//considers it as graceful completion of RunAsyn(CancellationToken).
}
catch(Exception ex)
{
// log error
throw;
// force service to restart, If an exception of any other type escapes from
// RunAsync(CancellationToken) then the process that is hosting this service
// instance is brought down
}
}
private async Task Start(CancellationToken cancellationToken)
{
while(true)
{
cancellationToken.ThrowIfCancellationRequested(); // honour cancellation token
try
{
await PollDatabase();
}
catch(Exception ex)
{
// log error
throw;
}
finally
{
for (var i = 0; i < 12; i++)
{
cancellationToken.ThrowIfCancellationRequested(); // honour cancellation token
await Task.Delay(TimeSpan.FromSeconds(5), cancellationToken);
}
}
}
}
}
【问题讨论】:
-
我应该补充一点,当 Service Fabric 发出取消信号时,PollDatabase() 中没有发生异常
-
有一个
CloseAsync,但是RunAsync有一个CancellationToken和一个CloseAsync存在的事实令人困惑。为什么两者都需要?
标签: c# azure azure-service-fabric cancellation-token service-fabric-stateless