If you’ve entered into the world of Windows Phone or Windows8/WinRT development then you know that EVERYTHING has to be done asynchronously. Whether that is a good decision, I’ll leave that up to you. Even Microsoft realized what a huge pain this was and decided to make this “easier” by adding language features – namely the “async” and “await” keywords.
Microsoft will likely be very upset to find out that I’m not really enjoying these keywords – and yet I’m stuck having to use them, as far as I know?
In all fairness, these keywords are good and useful – in that they save you from writing lots of code – and it makes code much easier to read. The downfall though is it doesn’t seem to quite work the way they claim, and it’s remarkably tough to debug.
For my own reference, here is a quick example of how this might work:
static void Main(string args)
Task task = LongRunningTask();
static async Task LongRunningTask()
await Task.Run(() =>
Console.WriteLine("Long-running task (Part I) complete.");
await Task.Run(() =>
Console.WriteLine("Long-running task (Part II) complete.");
Long-running task (Part I) complete.
Long-running task (Part II) complete.
From what I’ve gathered so far, await is meant to be a pretty clever use of threading (via Tasks). When you have the await keyword before a method call (or delegate), it will dispatch that code into a “Task” (which is handled by the Task Parallel Library, which makes efficient use of a multi-code processor) – and it will continue running other code (outside of the current method). When that original task completes, the run-time will spin up a new thread to CONTINUE execution on the next line after the await. The point being that you can “await” the completion of a task without blocking a thread. The other thing that makes this complexticated is that you often need to update the UI. That, as you may know, can only be done via the main/UI thread. So, the ExecutionContext and other things like CancellationTokens need to be managed. The next thing you know, you have some complex code just to deal with the overhead of this.
So, I’m gathering that async/await are meant to address all of that, because it invisibly keeps track of the ExecutionContext and you can gain access to the CancellationToken via the Task’s that are passed around everywhere.
“What’s the problem then?” you ask? Well, I have a couple of cases where I’m using WinRT methods where you HAVE to use the “await” keyword. That means the containing method MUST be marked as “async”. In my case, I actually need this to be asynchronous. Well, I should say that I need to wait until Part A is done before I start Part B. I have it coded correctly, as far as I know, but it simply doesn’t work correctly.
So add to the problem, I can step into the code with the debugger. When I do, the debugger basically runs all the code synchronously and it works as expected. I run that same code outside of the debugger and it just doesn’t work the same. The complexity comes in when you have async methods that call other async methods, which call other async methods. You end up with several tiers of code that are “awaiting” – but what is the run-time ACTUALLY doing? I don’t know – it’s very tough to figure out, that’s for sure. That’s what I’ve been bogged down in for a couple of days. If I manage to figure out how to sanely use async/await, I’ll do another blog post. Meanwhile, if you have any good links or resources – please let me know or leave a comment below, thanks!