【问题标题】:Azure Service Fabric How to rerun RunAsync method when completed?Azure Service Fabric 完成后如何重新运行 RunAsync 方法?
【发布时间】: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


【解决方案1】:

能否让轮询方法返回Task&lt;T&gt; 而不是Task?您可以在您选择的对象中返回原因。

https://blog.stephencleary.com/2012/02/async-and-await.html

【讨论】:

  • 我实际上需要知道为什么 Service Fabric 需要关闭这个服务实例。由于池方法抛出异常,这不会发生。
【解决方案2】:

Service Fabric 决定从 RunAsync 方法正常返回后,如何再次重新运行轮询例程?

据我了解,RunAsync 返回后会再次调用。 在Reliable services lifecycle overview,您可以阅读以下内容。

对于有状态的可靠服务,如果服务从主服务降级然后再提升回主服务,则会再次调用 RunAsync()。

您还可以在那里阅读降级和升级的主副本的生命周期,其中不包括 OnCloseAsync。

我如何才能确定 Service Fabric 首先发出取消令牌信号的原因?

恐怕您需要搜索抛出的异常。请注意,我不确定这个答案,这只是我的怀疑。

【讨论】:

    猜你喜欢
    • 2016-09-28
    • 2019-11-30
    • 2018-11-06
    • 2017-01-29
    • 2019-08-31
    • 1970-01-01
    • 2017-06-05
    • 2018-10-27
    • 2018-04-07
    相关资源
    最近更新 更多