Waaaaay oversimplified async/await plumbing

[cross posted from my MSDN blog]

Often, when someone asks “how does this async await stuff actually work”? There is a lot of hand waving or someone says “just use reflection and look at it” but the real compiled code is a complex recursive state machine. So I want to show a (relatively) simplified example that isn’t the real thing but is conceptually correct.

Conceptually, the way I think about it is that the compiler just breaks down my method into a series of tasks that need to be run. Lets start with a simple scenario which has a single await.

image

We kind of hide the Task by default but if you change it to look like this, you can see we aren’t awaiting the method, we are awaiting the Task returned from the method.

image

Now we can take the async/await keywords away by breaking the method up into 2 areas – the code that runs before the await, and the code that runs after the await. Because the GetCountAsync() call is async, we can’t run that “after” code immediately. We want to wait until after countTask is complete and then run the “after” code. So what actually runs looks more like this

image

As you can see, we have taken the “after” code and told it to run as a continuation of the countTask. This means that the GetCountAsync method will run and whenever it gets done, the “after” code will execute. Of course this means we have another task to deal with. The “after” code continuation provides us a new Task object to know when that is done. When that is finished we know that our entire method is finished. So we can return that final Task to the caller of our method so that they will know when we are complete.

Now this is definitely not a complete picture (e.g. we are not dealing with looping or exceptions or managing the UI thread). But I find this a pretty compelling way to demonstrate a couple of key principles.

  1. When you use the async keyword, your method becomes asynchronous because it gets broken into Tasks based on the await keywords in use.
  2. Your async method will return before it completes. Yes, that’s the whole point and is obvious to some people, but here it is shown explicitly because in the final example above, our method isn’t doing any real work except creating the Task chain and then returning.
  3. The code before the first await always runs synchronously. There is no Task management going on until you hit the first await. So if you have a 10 second operation before the first await, the method will take 10 seconds and then hook up the task chain and return.
  4. This is why your callstack looks different when debugging. The “after” code is not being called from DoWorkWithoutAwait(). It is being called directly from the .NET Task infrastructure as a continuation of the previous task.

Taking that a bit further

Lets take that concept and apply it to a more realistic method which contains  multiple awaits.

image

In the same steps, we can think of this as dividing our method up into a number of intermediate Tasks separated by the await keywords.

image

Again, this just demonstrates those same points that I see some developers forget or struggle with. When I see a series of await keywords, I’m thinking about how that method gets broken down into individual tasks – not how it is going to run as a single unit. This helps me remember that even if this ends up running on a single thread, the fact that is gets chunked up means that other scheduled code can potentially run in between my method’s various sections. You can also see this concept graphically in this previous post.

 

Additional files

Posted in Windows Phone | Tagged , , , | Leave a comment

Tasks are (still) not threads and async is not parallel

[cross posted from my MSDN blog]

I talk to a lot of developers who are either new to .NET or are moving from an older version to the newer platform and tools. As such I’m always trying to think of new ways to describe the nature of Tasks vs Threads and async vs parallel. Modern .NET development is steeped in the async/await model and async/await is built on the Task model. So understanding these concepts is key to long term success building apps in .NET.

In order to help visualize this I built a simple WPF application that displays a chart of an application’s activity. I want to display some of the potential variations in behavior of what appear to be a simple set of async tasks.

Take the following method

start code

This is a simple event handler which is going to call 3 asynchronous methods and then wait for all three to complete and then print out how long it took to do the whole operation. How many threads are there? Some people will assume only 1, some will assume 3. Like everything in software, it depends.

The DoWorkAsync() method just runs a loop. Each time around the loop, it will do some sort of asynchronous task and then do some busy “work” for some amount of time, then it will draw a rectangle on the screen representing the time that it spent doing that “work.” (This is analogous to making a web service call and then doing some local processing on the data returned from the service.) In this way we can easily see (a) when the work is being performed, and (b) whether the work overlaps with other task’s work. If it does, then we are running on multiple threads. The work we are concerned with is our code (e.g. the local data processing) – not the thing being waited on (the async web service), so each bar in the app will represent the local processing.

no-async code

The first case is the simplest, the method is marked as async but we really don’t have any asynchronous work going on inside it. In this case, the method is actually going to actually run to completion synchronously, meaning that the tasks above (in the event handler) will all be complete immediately upon creation and there wont be any new threads. They will each just run one right after the other.

no-async

In this image, the vertical axis is time. So first the red task ran, then the blue task ran, then the green task ran. It took 5 seconds total because 5 loops * (200ms + 300ms+ 500ms) = 5 seconds. You can also just make out the faint white lines of each individual iteration of the loops. But only 1 thread was used to run all three tasks.

Now lets make one change. Add an asynchronous operation where the //TODO is. Typically this might be a web service call or reading from a file, but for our purposes we will just use Task.Delay()

regular-async code

The only change here is the addition of the Task.Delay to the beginning of the loop. This will cause the method to not complete synchronously because it is going to do an asynchronous wait at the start of every iteration of the loop (simulating our async service call wait). Now look at the result.

regular-async

It still took about the same amount of time, but the iterations are interleaved. They are not overlapping each other though because we are still on the same thread. When you “await” an asynchronous task, the rest of your method will continue running in the same context that it started on. In WPF, that context is the UI thread. So while the red task is doing its delay, the blue and green tasks are running on the UI thread. When the red task is done delaying and wants to continue, it cant until the UI thread becomes available so it just queues up until its turn comes back around.

(Also notice that we didn’t add 1.5 seconds (100ms * 5 iterations * 3 tasks) to the total operation time. That’s the async benefit, we were able to overlap the waiting time of one task with the work time of other tasks by sharing the UI thread while we were waiting.)

But sometimes, this interleaving doesn’t happen. What if you have an asynchronous task that finishes so fast, it might as well be synchronous?

async-completed synchronously code

When the async plumbing goes to work, it first checks to see if the async operation is completed.  Task.Delay(0) will be completed immediately, and as such will be treated like a synchronous call.

async-completed synchronously

Well that puts us back to where we started. All 5 red iterations happen first because there is no asynchronous work to wait on.

Everything happens on the same thread context unless you tell it not to. Enter ConfigureAwait().

async-config await false code

ConfigureAwait(false) tells the async plumbing to ignore the thread context, and just continue on any old thread it wants. This means that as soon as the red task is done with its delay, it doesn’t have to wait for the UI thread to be available. It runs on a random threadpool thread.

async-config await false

Two things to notice here. First, since they are not bound to only running on the UI thread, they are running overlapped at the same time on multiple threads. Second, it only took 3 seconds to complete all three because they were able to fan out across multiple threads. (You can explicitly see the Task.Delays here because they are the white gaps between each bar)

Now what happens if we combine Task.Delay(0) with ConfigAwait(false)?

async-completed synchronously config await false code

Now we have a async task that will actually complete synchronously, but we are telling it not to bother with affinity for the threading context.

async-completed synchronously config await false

Completed synchronously wins. If the task completes synchronously already, then the async plumbing doesn’t come into play.

Summary

Look at this from the perspective of the original event handler above. The event handler has absolutely no idea whether its tasks are going to run on one thread or multiple threads. All it knows is that it has requested 3 potentially asynchronous tasks to be completed. The underlying implementation will determine whether additional threads come in to play or not. And whether you have multiple threads determines whether you run in parallel or not. So you need to be prepared for either behavior when writing and debugging your app because in the end, it just depends.

(Side note: The parallel behavior above is a side effect of the async/await thread context affinity in the WPF task scheduler. It is not guaranteed and the behavior may vary depending with different task schedulers. It should not be relied upon as a method to create other threads. If you require something to run in parallel, use Task.Run())

The example project used here is available in my GitHub repository.

Posted in Dev Stuff, Programming | 2 Comments

Visual Studio Tip #7: Whole line editing

[cross posted from my MSDN blog]

OK here is a quick simple one. How do I move or edit entire lines of code?

#1 Just don’t select anything.

If you don’t have anything selected in your code window then the commands for copy, cut and paste work as if the entire line of code was selected.

So if you need to quickly duplicate a line, don’t bother trying to get a whole line selected. Just put the cursor on the line then type Ctrl+C, Ctrl+V and you’ll see the new line pasted below the old line.

#2 Just move the line. Put your cursor on the line in question and use Alt+UpArrow or Alt+DownArrow to move the entire line up or down in your file.

This post is part of a series of Visual Studio tips. The first post in the series contains the whole list.

Posted in Windows Phone | Leave a comment

Visual Studio Tip #6: Turn on those line numbers (with Quick Launch)

[cross posted from my MSDN blog]

Writing code is very often a collaborative process and to discuss something you need to be able to refer to it. The simplest way to refer to a line of code is “look at line #26.” For some reason though, line numbers are not on by default. Before Visual Studio 2013 (which syncs your preferences across machines) turning on line numbers was one of the very first things I did on a every new computer.

Now how to do that? – Quick Launch! Visual Studio is a massive product with tons of options. Finding the one you need is more easily done via search. The Quick Launch box(that text box in the upper right on the title bar of the window) searches Visual Studio instead of searching your code (use Navigate To for searching code).

1 - quick launch

To find the options regarding line numbers, just type “Line Numbers” into the Quick Launch window and it will show you what it finds in the options dialog, the menus, and any open documents names & paths (but not the contents).

2 - line numbers search result

Select the item in the Options section. It tells you how that the Line Number option is in the General tab of the All Languages section of the Text Editor options. Visual Studio will open the Options dialog to the correct page. Check the Line Numbers box and close the dialog box.

3 - options dialog

Other stuff – you might have noticed the Task section of the Quick Launch results. Sometimes there are tasks you can run directly as well. In this case I could have just clicked the task and it would have changed the setting for me without opening the dialog.

This post is part of a series of Visual Studio tips. The first post in the series contains the whole list.

Posted in Windows Phone | 3 Comments

Visual Studio Tip #5: Quickly adding a namespace “using” statement

[cross posted from my MSDN blog]

One thing that slows down new C# users is the requirement to add “using” statements to the top of your file. This is because they just want to declare a variable and use it but aren’t necessarily familiar enough with the classes and namespaces to have predicted the need for the namespace when they were at the top of the file. So they end of hundreds of lines into a file and realize that the class they need to use requires a using statement all-the-way-at-the-top.

There are a couple of ways to add a using directive to your file to include the namespace. The obvious way is to scroll all the way to the top of your file and type it in. But that’s also the slowest and most error prone and takes you away from the line of code you are working on. The quickest way is just two key strokes and doesn’t move your cursor.

Imagine we want to write this method

image

The WebClient class is in the System.Net namespace which is not one of the ones usually included in a newly created file. So when you start to use it you get red squigglies because you need to put “using System.Net;” at the top of the file

image

But don’t scroll all the way up there. Instead, when you finish typing the class name, keep your cursor on the word WebClient (or right at the end). Then press the Control key and the Period key   (Ctrl + ‘.’)

This will reveal the Resolve menu

image

The first item is highlighted and says “using System.Net;” so press Enter to accept that. Visual Studio will put that using statement at the top of your file with the others. You will know that it is there because the WebClient text will change color to indicate it is a now recognized type.

image

then just continue typing in the rest of your code.

image

There are other ways to do this such as right clicking on the word WebClient and looking for “Resolve” in the context menu but I find that the simple keystrokes of Ctrl+ ‘.’ and Enter are quick and efficient because my cursor never moves and interrupts my code writing flow. This will work for any symbol that your cursor is on – as long as the assembly for the type is already added to your references.

This post is part of a series of Visual Studio tips. The first post in the series contains the whole list.

Posted in VSTips | Leave a comment

Visual Studio Tip #4: Code Snippets

[cross posted from my MSDN blog]

There is lots of code that we write that follow standard patterns with some minor changes for our exact situation. Visual Studio has a nice feature called Code Snippets which provides a way to create reusable code templates for common scenarios. The idea is that you activate the snippet, then just enter the needed values.

The ones I use the most are the snippets for .NET properties. There are actually two, one called “prop” and another called “propfull”. The code snippets are available from intellisense, so if I start typing “prop” inside my class and I can see the snippet

snippet1

Then I select the snippet (hit Tab once to select the item in intellisense)

Then hit Tab again to activate the snippet. This is the result

snippet2

 

A template of code is inserted and activated. Notice the two yellow rectangles? Those are the values I need to enter. Its like a little form for my code. In the image, the cursor is on the “int” one. If I press Tab again, it will select the next rectangle. In this way I can just type a new value in the rectangle, then press Tab to move to the next rectangle and enter the value there. So I just tab from one box to the next, changing values as needed and when I’m done, I press Enter and go back to regular code entry mode.

Try this: type “prop”, <Tab>, <Tab>, “string”, <Tab>, “Name”, <Enter>

You will end up with a simple property of type string named Name.

snippet3

Now try the propfull snippet.

type “propfull”, <Tab>, <Tab>, “string”, <Tab>, “_city”, <Tab>, “City”, <Enter>

snippet4

The propfull code snippet creates a full Property with a field to store the property’s value. Notice that when you entered “_city” that it changed in all 3 places in the code snippet.

Using these two code snippets you can very quickly fill out a new class’s properties.

There are lots of built in code snippets for lots of different things and you can also easily create your own (like I did for Windows 8 apps). To discover what’s available, you can right click anywhere in your code and select “Insert Snippet” and you’ll get access to all the snippets by category. (If you work in XAML be sure to check out propdp and propa)

For more on Code Snippets see the documentation.

This post is part of a series of Visual Studio tips. The first post in the series contains the whole list.

Posted in VSTips | Leave a comment

Visual Studio Tip #3: Use “Navigate To”

[cross posted from my MSDN blog]

I spend a lot of time looking at other people’s code. That means a lot of time searching other people’s code. One of the main tools I use is not Search but “Navigate To”. It is found on the Edit menu or you can use the keyboard shortcut “Ctrl + Comma” to bring up this tiny window in the upper right corner of your code window.

Then just type and Visual Studio will search code files, file paths and code symbols in real time. If you select an item, that file will be displayed in the temporary reusable tab. It does not do a full substring text of your code though, so it gives a more focused search result. For example, if I search “viewmodel” get the viewmodel classes and files, but I do not get any results where I use the term “viewmodel” in the comments.

There are two handy refinements you can add into the mix here.

First is prefacing your query with ‘@’. That will refine the results down to just code symbols

Second is to use camel casing. If you use all caps camel casing you can pull up items without having to spell the whole thing out. This comes in very handy when dealing code that has long symbol names.

NOTE: Navigate To has been in Visual Studio for a while but it changed to this implementation in VS 2013. If you only have VS 2012 you can install the Power Tools for VS 2012 and get this behavior.

This post is part of a series of Visual Studio tips. The first post in the series contains the whole list.

Posted in Programming, VSTips | Tagged | Leave a comment