C# Azure服务结构如何在完成时重新运行RunAsync方法?

C# Azure服务结构如何在完成时重新运行RunAsync方法?,c#,azure,azure-service-fabric,cancellation-token,service-fabric-stateless,C#,Azure,Azure Service Fabric,Cancellation Token,Service Fabric Stateless,我有一个无状态服务,在RunAsync方法中运行后台进程 此后台进程必须永远运行。它所做的与此无关,但它基本上每60秒轮询一次数据库 与工作者角色或WebJob不同,服务结构服务中的RunAsync方法可以一直运行到完成,并且服务实例将保持运行状态 当服务结构向传递给RunAsync的取消令牌发出信号时,就会发生这种情况 一旦服务结构决定从RunAsync方法正常返回,我如何再次重新运行轮询例程? 我如何确定为什么服务结构首先发出取消令牌的信号? 我当前的解决方法是抛出异常,以便强制重新启动服务

我有一个无状态服务,在RunAsync方法中运行后台进程

此后台进程必须永远运行。它所做的与此无关,但它基本上每60秒轮询一次数据库

与工作者角色或WebJob不同,服务结构服务中的RunAsync方法可以一直运行到完成,并且服务实例将保持运行状态

当服务结构向传递给RunAsync的取消令牌发出信号时,就会发生这种情况


一旦服务结构决定从RunAsync方法正常返回,我如何再次重新运行轮询例程?

我如何确定为什么服务结构首先发出取消令牌的信号?

我当前的解决方法是抛出异常,以便强制重新启动服务

    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);
                    }
                }

            }               
        }
    }
公共类无状态1:无状态服务
{       
受保护的覆盖异步任务RunAsync(CancellationToken CancellationToken)
{
尝试
{
等待启动(取消令牌);
}
捕捉(操作取消例外)
{
投掷;
//如果一个OperationCanceledException从
//RunAsync(CancellationToken)和服务结构运行时已请求
//通过发送信号取消传递给的cancellationToken进行取消
//RunAsync(CancellationToken),服务结构运行时处理此异常并
//将其视为RunAsyn(CancellationToken)的优雅完成。
}
捕获(例外情况除外)
{
//日志错误
投掷;
//如果从中逃逸任何其他类型的异常,则强制重新启动服务
//RunAsync(CancellationToken)然后是承载此服务的进程
//实例被打倒
}
}
专用异步任务启动(CancellationToken CancellationToken)
{
while(true)
{
cancellationToken.ThrowIfCancellationRequested();//荣誉取消令牌
尝试
{
等待数据库();
}
捕获(例外情况除外)
{
//日志错误
投掷;
}
最后
{
对于(变量i=0;i<12;i++)
{
cancellationToken.ThrowIfCancellationRequested();//荣誉取消令牌
等待任务延迟(TimeSpan.FromSeconds(5),cancellationToken);
}
}
}               
}
}

您能让轮询方法返回
任务而不是
任务
吗?您可以在选择的对象中返回原因


一旦服务结构决定从RunAsync方法正常返回,我如何再次重新运行轮询例程?

据我所知,RunAsync返回后将再次被调用。 在上面,您可以阅读以下内容

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

您还可以从中了解降级和升级的主副本的生命周期,其中不包括OnCloseAsync

我如何确定为什么服务结构首先发出取消令牌的信号?


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

我应该补充一点,当Service Fabric发出取消信号时,PollDatabase()中没有发生异常,
CloseAsync
,但是
RunAsync
获得一个
CancellationToken
和一个
CloseAsync
存在的事实令人困惑。为什么两者都需要?我实际上需要知道为什么Service Fabric需要关闭此服务实例。这不会发生,因为池方法引发异常。