I'm trying to use the Enterprise Library Transient Fault Handling Application Block ("Topaz") to implement a retry policy for asynchronous calls to Azure storage and it's not how to combine the two correctly.
Should I use RetryPolicy.ExecuteAction()
or RetryPolicy.ExecuteAsync()
?
For example (async execute and async addmessage):
public async Task AddMessageToQueueAsync(string message)
{
await myRetryPolicy.ExecuteAsync(() => azureQueue.AddMessageAsync(message));
}
or (synchronous execute and async addmessage)
public async Task AddMessageToQueueAsync(string message)
{
myRetryPolicy.ExecuteAction(async () =>
await azureQueue.AddMessageAsync(message));
}
or (async execute and synchronous addmessage)
public async Task AddMessageToQueueAsync(string message)
{
await myRetryPolicy.ExecuteAsync(() => azureQueue.AddMessage(message));
}
I need to await the task one way or the other, as I can't continue until the message has been successfully delivered to the queue.
What I'm finding is that the first example ends up firing off a task that fires off as task that adds a message to the queue -- rendering my await call useless - that is, await ExecuteAsync()
returns immediately but the "inner" AddMessageAsync() task is still running. Since this code is being called by an MVC controller action, I end up with an exception that the action completed while there was an asynchronous operation pending.
The other two examples seem to work, but neither one feels right.