CancellationToken doesn't get triggered in the

2019-05-05 01:57发布

问题:

I've got this simple Azure Function:

public static class MyCounter
{
    public static int _timerRound = 0;
    public static bool _isFirst = true;

    [FunctionName("Counter")]
    //[TimeoutAttribute("00:00:05")]
    public async static Task Run([TimerTrigger("*/10 * * * * *")]TimerInfo myTimer, TraceWriter log, CancellationToken token)
    {
        try
        {
            log.Info($"C# Timer trigger function executed at: {DateTime.UtcNow}");
            if (_isFirst)
            {
                log.Info("Cancellation token registered");
                token.Register(async () =>
                {
                    log.Info("Cancellation token requested");
                    return;
                });
                _isFirst = false;
            }
            Interlocked.Increment(ref _timerRound);
            for (int i = 0; i < 10; i++)
            {
                log.Info($"Round: {_timerRound}, Step: {i}, cancel request:{token.IsCancellationRequested}");
                await Task.Delay(500, token).ConfigureAwait(false);
            }
        }
        catch (Exception ex)
        {
            log.Error("hold on, exception!", ex);
        }
    }
}

What I'm trying to do is capturing the CancellationToken request event when the app stops or a code redeploy happened (host shutdown event).

BTW, I've also tried to check the IsCancellationRequested property in the for loop as well. Never turns true.

The main requirement is not to loose any operation/data during the function deployments, I want to know that the app is being stopped so that I persist some data to be processed once host started again after update.

回答1:

Based on your code, I tested it on my side, here are my test result:

From the above screenshots, we could find that the subsequent rounds could not handle the cancellation callback except the first round. As Fabio Cavalcante commented, I removed the _isFirst logical checking and found it could work for all rounds as follows:

Note: I simulated the shutdown of my host by disabling my function when the TimerTrigger is triggered.