Thanks for the video, guys! Queues and separation of backend processing is an important subject that a lot of developers don't see the need for, and I'm sure these videos will be helpful!
I do have a few corrections regarding the async/await usage (mainly talking to others who are going to be watching this video):
First, keep in mind that the threading situation is very different in the front-end (WebAPI) in the Post method, and in the back-end (worker role). In WebAPI, you're in ASP.NET; whereas the worker role is just a single thread.
- An async WebAPI method should return Task or Task<T>, not void. If you actually call this code, ASP.NET will catch this mistake and throw an InvalidOperationException with the rather confusing error message "An asynchronous module or handler completed while an asynchronous operation was still pending." The fix is to make Post into an async Task method instead of async void.
- It's not actually "fire and forget". ASP.NET keeps track of all asynchronous methods that have not yet completed. So, even though your code doesn't have to handle it, ASP.NET does. To be clear, "fire and forget" is extremely dangerous on ASP.NET and most server scenarios.
- In the ASP.NET threading model, you don't want to call Wait on a Task. This will immediately negate all the scalability benefits of async/await, among other problems. If you need to apply a timeout, use cancellation, as such:
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5));
await queue.AddMessageAsync(msg, cts.Token);
- In the worker role thread, you can use Wait. Although, the code "queue.CreateIfNotExistsAsync().Wait()" is not doing anything more than "queue.CreateIfNotExists()" would.
- The video made a good point that you can't make a worker role Run method async. This is a common mistake.
- When you create a new asynchronous method (e.g., DoStuff), you should default the return type to Task or Task<T>, not void. Async void methods cause lots of problems.
- Task.Factory.StartNew does not understand async methods, so the LongRunning option actually doesn't do anything. It's better to just use Task.Run, which was designed for use with async methods.
For more information on general async best practices:
and StartNew in particular: