Deadlocking is really something you need to avoid and in case you don’t know what a deadlock is here’s a great illustration of a “real life deadlock”:
Basically what has happened here is that all the roads are full with cars and all the cars try to cross the road at the same time. Let’s translate this into computer terms; the cars in this case are the threads and the cross-over is the “thing” that handles these threads. In the illustration above all the cars have driven into the cross-over at the same time and they can’t really back up, hence there’s a deadlock and there’s no way to go.
What happens in a computer program when you get a deadlock is that it freezes and there’s no where to go because all paths are occupied or waiting for something to finish. Let’s say that process X waits for process Y and process Y waits for process X and both of these lock up the GUI thread, this means that the application will die. Hence deadlocking is something you want to avoid.
Normally you solve this by introducing locking and semaphores. As discussed in the article linked above (where I got the very nice illustration) a semaphore can be seen as a traffic light which handles how the cross-over is loaded with cars.
A while back I wrote an article called “Avoid shooting yourself in the foot with Tasks and Async”, I suggest that you should always return a Task from your asynchronous methods and you really should. What I am about to tell you below though is what you should avoid when doing this.
When a method is marked as asynchronous and the await-part is reached, the method will “exit” and return the “awaiting Task“, which means it’s not the Task that runs inside the method but in fact a Task that keeps track of the status of the asynchronous operation.
Let’s look at a basic code sample!
Consider that you have the following basic asynchronous method, all it does is that it waits for 2 seconds and then prints something to the debug window:
private async Task RunAsync() {
var run = Task.Factory.StartNew(()=>{
Thread.Sleep(2000); });
await run;
Debug.WriteLine("Execution done!"); }
Once await is reached, what will happen? A Task will be returned, but which one? Not the one named run! A Task that keeps track on the state machine will be returned.
Now what happens if we call this method on the GUI thread and asks to wait for it to finish? Calling Wait freezes the current thread and since we are on the GUI thread this will freeze the GUI thread, but for how long? When is Wait happy enough to proceed? In fact it will wait for the asynchronous task that handles the state machine to give it a signal that it’s now ready.
However that Task can never be marked as done until the entire method has been completed. Which means that it needs to access the GUI thread again, since we’re back on the calling thread (GUI thread in this case) after await!
This means that all we have to do in order to deadlock is this:
RunAsync().Wait();
I hope that makes sense to you and gives you an insight into what really happens when you use async and await. As with everything: use it wisely and know what it is that you’re doing.
Do you ever get the feeling that you want to know exactly what happens behind the scenes? I do, quite a lot actually. Which is one of the many reasons that I’ve written about IL, Reflection and ways to prove how certain code behaves and works using tools such as Reflector. If you’ve read my book C# Smorgasbord, you might have come across the chapter about async & await which are two very handy additions to .NET 4.5. I’ve done some screencasts and articles about that in the past, but let’s take a look at something that we haven’t looked at before; what happens behind the scenes.
As you might know, when you use async and await in .NET 4.5 an internal state machine is created to keep track of the current state. Jon Skeet had a brilliant talk on NDC 2010 where he talked about how goto is truly awesome, in the essence of async & await that is. Without it async & await would be hard to implement accordingly.
This won’t be one of my lengthy posts, this time I’ll leave some of the investigation to you and we might re-visit the topic in the future. Leave a comment about what you think of it all below!
I created a very simple .NET 4.5 console application in Visual Studio 2012 which I named AsyncDemoProject. In this application which you can see below I just created a very simple async operation which I want to inspect further.
The most simple application that I could think of creating was one that simply creates a task that sleeps for a while then returns a string. What my application then does is simply awaiting this and setting a property to a value that indicates that the operation is done.
This ended up looking like the following:
class AsyncDemo { publicbool IsLoading { get; set;} public async Task GetStringAsync() {
IsLoading =true;
var result = await GetStringTask();
IsLoading =false;
Console.WriteLine(result); }
public Task<string> GetStringTask() { return Task<string>.Factory.StartNew(()=> {
Thread.Sleep(2000);
return"Hello World"; }); } }
This can be used as simple as this:
staticvoid Main(string[] args) {
var demo =new AsyncDemo();
demo.GetStringAsync();
while(demo.IsLoading) {
Console.WriteLine("Async is Amazing no?!!!"); }
Console.ReadLine(); }
What happens when we run this is that a console will be opened and after about two seconds we will see a message telling us “Hello World” of course the console will be filled up with the text “Async is Amazing no?!!!” until that message is shown and that loop is exited due to the condition being met.
If you have a tool installed such as Reflector or IL Spy, open up the compiled executable in that and let’s inspect what happened when we compiled this solution. This did generate some interesting things, normally when you compile an application and open it up in reflector, you will be able to see something pretty much alike what you programmed in the first place. But when adding async and await we have some generated code that needs to be there in order for the state machine to work properly.
Notice that we have a struct generated for us, it even has the attribute CompilerGenerated! This struct keeps track of the state and has methods to help us with that. In reflector we can expand the methods to see the implementations, if we do so, this is what we will see:
Notice the use of label and goto? You might recall the use of label when we jumped around with IL in some of the previous posts on this blog. As you can see the code isn’t really “exactly” as you might imagine from the use of some simple keywords. There’s a lot of magic that happens and above in the code example you can see how the state machine is implemented and how it is used.
Quite interesting right? Let me know what “chocked” you the most about the code generated from asyc and await.
Since the release of .NET 4.5, you’ve been able to use the RTM version of Async & Await. There are some things though that can lead to very weird behaviors in your applications, and a lot of confusion. Kevin (Pilchie) over at Microsoft just gave me heads up on some of these and I thought that I would share it with the rest of you!
There was a very interesting discussion around this subject in the ##roslyn channel on freenode with @ermau and @jrusbatch.
Avoid async void
When you’re doing asynchronous methods that just return void, there is no way to track when these methods are done.
Look at the following example:
class FooBar { public async void Biz() {
await Foo(); } public Task Foo() { return Task.Factory.StartNew(()=> {
Task.Delay(2000);
Console.WriteLine("Done!"); }); } }
If we create an instance of FooBar and call Biz(), there’s no way for us to wait for the task to finish. Normally we would want a reference to a Task that we could wait for to finish, but in this case we don’t! Avoid async void whenever you can.
Just change the method signature to async Task instead and you will be able to do:
We would indeed get an exception thrown. But we would only get One exception thrown! In fact, the only exception that we will get is the First exception being thrown.
This means that we would not see an aggregated exception list as we might expect.
Exceptions in Tasks don’t travel back to the caller
When working with multiple threads and the thread causes a problem that is unhandled, these are thrown back at the caller.
No exception were traveled back to the caller, this can cause potential confusions. This is actually by design and MSDN says the following about it:
In the .NET Framework 4, by default, if a Task that has an unobserved exception is garbage collected, the finalizer throws an exception and terminates the process. The termination of the process is determined by the timing of garbage collection and finalization.
To make it easier for developers to write asynchronous code based on tasks, the .NET Framework 4.5 changes this default behavior for unobserved exceptions. Unobserved exceptions still cause the UnobservedTaskException event to be raised, but by default, the process does not terminate. Instead, the exception is ignored after the event is raised, regardless of whether an event handler observes the exception.
If we want the the .NET 4 behavior, we can re-enable the unobserved task exceptions by changing the applications app.config. Add the following to the app.config:
This will tear down the process as it did in .NET 4.0.
Unhandled Exception: System.AggregateException: A Task’s exception(s) were not observed either by Waiting on the Task or accessing its Exception property. As a result, the unobserved exception was rethrown by the finalizer thread. —> System.Exception: Exception of type ‘System.Exception’ was thrown.
Have you ever shot yourself in the foot with Tasks or Async? Leave your horror stories in the comment field!
Since the fall 2011 I have been working on a book called C# Smorgasbord. The book is inspired by all the interesting topics that I’ve touched in this blog.
I’m proud to announce that the book will soon be available for purchase on Amazon and CreateSpace! You will also be able to purchase digital copies on the website for C# Smorgasbord.
It will be available for purchase August, 2012.
The cover
The cover is produced by a very talented art directory, Christoffer Saltelid and looks like this:
3D-view of the book
A little bit about the book
Looking at everything from testing strategies to compilation as a service and how to do really advanced things in runtime; you get a great sense of what you as a developer can do. By taking his personal views and his personal experience, Filip digs into each subject with a personal touch and by having real world problems at hand, we can look at how these problems could be tackled.
No matter if you are an experienced .NET developer, or a beginner, you will most certainly find a lot of interesting things in this book. The book covers important patterns and technologies that any developer would benefit from mastering.
Table of Contents
This is the top-level Table of Contents for C# Smorgasbord:
Introduction to Parallel Extensions
Productivity and Quality with Unit Testing
Is upgrading your code a productive step?
Creating a challenge out of the trivial tasks
Asynchronous programming with async and await
Dynamic programming
Increase readability with anonymous types and methods
Exploring Reflection
Creating things at runtime
Introducing Roslyn
Adapting to Inversion of Control
Are you Mocking me?
If you head over to books.filipekberg.se you can pre-order a digital copy today.
This is my second screencast, talking about the C# 5 async ctp. In this session I show how you can refactor old code that is using the task parallel library or a background worker to run time consuming operations asynchronously.
I also touch the surface on what continuation is and how it has been acheived using TPL and how it makes life easier when using async and await.
I recently recorded a screencast talking about the C# 5 Async CTP, keep in mind that this is my first screencast ever, so please give me your constructive comments.
Filip Ekberg is a Senior Software Engineer working in the country with all the polar bears, author of a self-published C# programming book and overall in love with programming.
Check out my recently published book.C# Smorgasbord covers a vast variety of different technologies, patterns and best practices that any C# developer should master.
All printed copies include access to the e-book bundle (PDF, ePub and Mobi!).