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.
The most common cause for Azure Functions not getting triggered is that triggers are not synced properly. You can sync triggers in one of three ways: Restart your function app in the Azure portal.
Determine which trigger works best for your business needs. Create a timer trigger to invoke a function on a consistent schedule. Create an HTTP trigger to invoke a function when an HTTP request is received. Create a blob trigger to invoke a function when a blob is created or updated in Azure Storage.
Navigate to your function app in the Azure portal, select App Keys, and then the _master key. In the Edit key section, copy the key value to your clipboard, and then select OK. After copying the _master key, select Code + Test, and then select Logs.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With