Wednesday, December 31, 2014

2014 in Review

It's the end of another year -- time to check my progress. I've done a lot of things this year, expanded some into some new areas, learned a lot of things, and got some surprises along the way. I kind of hate doing this article because I don't want to sound like I'm bragging. But it's important to reflect back and make sure that I'm productive and headed in the right direction. This is more for me than anyone else, so I won't be offended if you skip the rest. (Just look at the bold items for the short version.)

Doing Lots of Stuff
Speaking
I was really busy with speaking this year. I managed to do 40 presentations at 26 events. And I really love doing this. Whether it's speaking in front of 5 people or 125 people, I try to have a lot of fun and share my excitement about particular technologies with other people.

Central California .NET User Group
I try to find new places to talk each year. This year, I expanded north in California, speaking at user groups in Berkeley, San Francisco, Mountain View, and Fresno. In addition, I made it out to speak in Glendale AZ for the first time.

I also had a chance to speak at Code Camps in Salt Lake City UT, Chandler AZ, San Diego CA, Los Altos Hills CA, and Los Angeles CA. Code Camps are always a lot of fun. I love meeting new people, seeing old friends, and spending the day with folks who are interested in learning and improving their programming skills.

As something new, I also teamed up with some of my friends from the speaking community to put on 2 full day workshops. In May, Theo Jungeblut and I presented an Education Day in San Francisco (and big thanks for Mathias Brandewinder for coordinating things). And in September, Nuri Halperin and I presented "Leveling Up: The Professional Coder Workshop" in Hollywood (with big thanks to Hattan Shobokshi for handling all the event details).

It's really cool to look back at all the amazing chances I've had to speak this year. (And there's a full listing on my website: http://www.jeremybytes.com/Demos.aspx.)

Going Places
In addition to going places to speak, I've had a chance to go places just to participate. This included the Pluralsight Author Summit where I got to spend a weekend with some really great people who love to teach. It was inspiring to hear from the Pluralsight folks first hand about how passionate they are about finding the most effective way to spread knowledge.

I also went to Agile Open So Cal. This was an open spaces conference that focused on agile methodologies. I met some really great people there, and I had a chance to interact with analysts and coaches. I came away with some interesting ideas, and it made me look at some of my career experiences in a new light.
In Newport OR

And I had a chance to go to the Microsoft MVP Summit. It was great to see some of my old friends (well, I think of them as old friends even though we've only known each other for a few years), and it was great to make a bunch of new friends.

And completely unrelated to technology, I got to take a 3 week road trip all the way up to Vancouver BC. I drove up through the redwoods in Northern California, along the Oregon Coast, and up to Cascades National Park in Washington (with a day trip to the Greater Vancouver Zoo in Canada). It was a lot of fun, 4,000 miles of driving, completely exhausting, and totally worth it.

Pluralsight
I released 2 courses on Pluralsight this year. The first was way back in January: Introduction to Localization and Globalization in .NET. I'm not sure I should include this in this year's accomplishments because I did all the work for it in 2013 (the course was published on January 2nd).

In October, Pluralsight released Abstract Art: Getting Things "Just Right". This course was a lot of fun to do. I got to share my experiences and observations regarding developer behavior, under-abstraction, and over-abstraction. And my hope is that the course will help developers see the danger signs before it's too late.

YouTube
Last year I said that I wanted to expand my YouTube channel. This year I managed to release 9 videos, including a series on C# Generics and another series on C# Delegates. It takes me a full day to produce a 20-minute video. I may be able to speed up the process, but I'm very happy with the quality of the results with my current workflow.

I'd like to expand things further, and I've been a bit torn when I have a topic to share. Should share it in video form or in written form? I try to pick the best medium for the topic, but I know that different people learn in different ways. For the folks who learn better with video, I may end up duplicating my written material in video form. We'll see what the future holds.

Blogging
I've been trying to blog more. I managed to write 81 articles this year (if you include this one). Looking through them, I've found that I've been writing on all sorts of things. I've done quite a few technical articles that describe a keyword, operation, or technique. But I've also written a bit on development process and mindset. This included things like exploring software that grows organically, creating partnerships between developers and the business areas they write code for, and figuring out where to go next in your career.

One thing I find surprising is that I never know which articles will become popular. Sometimes I write a quick answer to someone's question, and it turns out into something that gets a lot of traffic. Here are the most popular articles that I wrote this year:
In addition, I've been writing exploratory articles where I'm documenting things as I learn them. We all learn new things all the time (that's the nature of the development profession). And I'm not afraid to say, "Yeah, I know this isn't new technology, but it's new to me." It's bound to be new to someone else, too. And that person can learn along with me.

New to Me
And speaking of things that I've learned, I feel like I've dipped into a lot of different topics this year.

Realizations
I must be getting old because I seem to be reflecting back on my experiences and career more and more often (and I'm only a half grey-beard right now). The good thing is that I've been recording these realizations. The biggest realization has to do with the idea of No Estimates and software by subscription. This started as a conversation with Woody Zuill at the Agile Open conference and turned into several blog articles (which have the "Agile" tag). It was interesting to look at my experiences in a new light -- not changing my opinions of what works, but refining them a lot more.

Explorations
I've been circling around functional programming for a while (check for the "Functional Programming" tag). This year I've been doing some more explorations. I've discovered that I've been using functional techniques in my code without realizing it (including my use of lambda expressions, LINQ, and delegates). And I've been working on ways to use these techniques more intentionally. Based on how things are going, I expect that I'll take the plunge into the world of functional programming very soon.

I also did an experiment to see what it really means to come up with a minimum viable product (MVP) (articles: Rewriting a Legacy Application). I'm sure that the application I used doesn't interest anyone -- especially since it's based on hardware that you can't get anymore. But this was a way for me to document my process of figuring out the MVP and the surprise of finding out just how "minimum" the MVP could be and still be useful.

And I've also been working with Git recently (look for the "Git" tag). I really feel like I'm late to the game with this one. But we can never get to everything. I'm really glad that I've started using Git, and I know that I have a lot more to learn.

Pre-Release Products
Something that is brand new to me is dealing with pre-release versions of products. I am not a trail-blazer when it comes to technology. But I ended up working with some preview stuff this year.

First is Roslyn (or the ".NET Compiler Platform"). This is another thing where I feel a little late to the game. But that's probably just because I have a circle of friends who have been working with this for several years now. I need to remind myself that this won't be officially released until next year. I built a diagnostic analyzer and then put together a video to show how to do it (Building a Diagnostic Analyzer with Code Fix in Visual Studio 2015). And I also came up with some optimizations later on that I shared in an article. This is still new to me, so I don't expect to get it right the first time.

Next, I took a look at Smart Unit Tests. This is something that is available in the Visual Studio 2015 preview. I looked at how it worked by running against some code that I had, explored some of its capabilities, and then tried it with some code that was a little more difficult to test. The technology really interests me, and even though I may not use it in my own workflow, I'm looking forward to seeing what's in the final release.

Jeremy and JSON at Silicon Valley Code Camp
A Great Year
Overall, it's been a really great year. I got 5 minutes of fame on the .NET Rocks! podcast. I was renewed as a Microsoft MVP for another year. I got to speak at a lot of events.

And my blog has been gaining in popularity. I've had several of my articles picked up by link aggregators (Thanks Alvin Ashcraft and Chris Alcock). That has driven quite a bit of traffic to my site and encouraged people to add my blog to their news readers.

So last year, I was happy to see 3,000 hits per month. To see how much things have changed, for the last 3 months I've been getting over 8,000 hits per month (and this month is over 11,000).

But one of the most rewarding thing is when I get a comment like this:
Jeremy has the unique ability to simplify complex subjects and to show the listener why they should care about learning about the subject he's teaching. In his live presentations, he uses humor and compassion to help make software development less dry and more fun.
And this (from a recent presentation on Dependency Injection):
After attending this presentation, I finally understood what DI is. The source code is fairly easy to follow, and I'm not a .Net developer. I'm so glad it finally clicked. Thanks Jeremy!
I really love to help people learn.

Looking Forward
I still have a lot of things to learn. I have a lot of things I want to do. And I have a lot of things I want to teach. I didn't get to everything I had planned this year. But I've also found that even though things don't go as I planned them, I often end up somewhere even better.

I'll keep moving forward and keep stretching myself. I'm excited about what the next year will bring.

Happy Coding!

Tuesday, December 30, 2014

Getting Used to Git in Visual Studio: Branches

I started working with Git not too long ago (here's how I got started). Soon after, I discovered the built-in support for Git in Visual Studio 2013. I've been working with Git and Visual Studio quite a bit over the last several days, so it's time for an update to show the things I really like.

I started by primarily using the command line. But as I've become more comfortable with the features in Visual Studio, I find myself using the VS GUI more and more. This is based on the project that I've been building for Exploring Task, Await and Asynchronous Methods (the GitHub project is at https://github.com/jeremybytes/using-task).

I've been using branches to document the various stages of the code, so I've had a chance to play with the branching and syncing functionality in Visual Studio. Let's take a look.

[Note: Git articles are collected here: Learning Git. And a video is also available: Git Basics for Visual Studio Developers.]

Creating Branches
The Team Explorer window has everything we need. To get back to the "Home" screen, just click the little house icon on the top of the window. This gives us a quick way to get back to the main menu for our source control:


From here, we can select "Branches" to see all of our current branches:


In addition to having a list of the branches, the bolded entry lets us know which branch we are currently on. In this case, we are on "master".

To create a new branch, we just click the "New Branch" item (it's sort of a cross between a link and a drop-down). It gives us the following options:


Now we can type in our new branch name, select which branch we want to base this on (in this case "master"), and we can also checkout the branch after it's created.

Here's what we get:


We can see a couple of things here. First, our new branch is bolded; this is the current branch. In addition, it is listed in the "Unpublished Branches" section. This means that this branch is on our local system, but it has not been published to our server.

Publishing Branches
Publishing our branch is very simple. We simply right-click on it and choose "Publish". This will push it to the GitHub repository that we have set up. And we can see that here:


Now the first time that we "Publish" a branch from our local repository, we'll need to enter the information for our server-based repository. For this project, we're already configured to go against the "using-task" repo on GitHub.

Changing Branches
It's very easy to switch between branches. Here's our "MainWindow.xaml.cs" file, and as we can see, this is on the "07-TestBranch" that we just created:


From here, we can double-click on a different branch, or we can select from the "Branch" drop-down at the top of the "Branches" window. If we choose the "03-Await" branch, we see that our source code updates automatically:


And if we have uncommitted changes, we'll get a warning that we need to deal with them before changing to a different branch -- by either committing the changes or discarding them.

I have found that this makes it very easy to jump among the branches. For my articles that use this solution, I wrote (and published) all of the code ahead of time. This let me work out what my code samples would look like for the article.

Then when it came time to write the article, I could switch to the various branches to take screen shots, run the application, and show the changes for each step along the way.

Now in production applications, I generally have very short-lived branches -- usually just long enough to create a new feature and then merge the changes back into the main branch. But if I did run into a situation where I needed to manage multiple branches, this would be a very convenient way to jump among them.

Comparing Branches
It's really easy to see the changes between branches as well. For example, we can right-click on "MainWindow.xaml.cs" in the Solution Explorer and choose "View History...". This gives us all of the commits that affect this file:


Notice that in addition to the commits, we can also see the various branches in our repository. So we can make selections based on individual commits or based on the state of a particular branch.

We can also easily do comparisons. If we select both the "07-TestBranch" and the "03-Await" items, right click and choose "Compare...", we get the difference window that we saw in a previous article:


This makes it really easy to see what was added or removed.

Syncing with GitHub
So let's say that we've made some changes to our "07-TestBranch". It's really easy to commit those changes locally and then sync them with GitHub.

After changing the file, we go to the "Changes" section in Team Explorer:


This shows that we have one file that has been changed. So we can add our message and click "Commit".

After we do this, we'll get a message that the changes have been committed, but we still need to sync them with the server. For this, we'll go to the "Unsynced Commits" section. (Remember, we can click the "Home" icon at any time to get back to the menu):


This shows that we have some local commits that need to be pushed up to the server. The great thing here is that we just need to click on "Push", and it handles everything else for us.

Merging and Clean Up
So let's say that we're done with this branch. We just want to merge this back to "master" and remove the branch from our repository.

Merging is very easy. We just go back to the "Branches" section and select "Merge". This gives us drop-downs to fill in:


In this case we want to merge from our "07-TestBranch" back to "master". This is especially nice since merging from the command-line is a bit more involved (first by switching to the branch you want to merge to, then entering the "merge" command with the name of the branch to merge from).

I'm not sure what happens if there are any merge conflicts. Quite honestly, I try to avoid those as much as possible, so I hope that I never have to find out.

It turns out that I changed my mind about publishing the branch. I really don't want this branch in the local repository or on the server repository. To unpublish a branch from the server, we just have to right-click on the branch and select "Unpublish branch".


The message at the top tells us this was successful, and our branch is now listed under "Unpublished Branches". And if we check GitHub, we'll see that the branch is now gone:


To delete the branch, we just need to switch to another branch first (we'll use "master"). Then we can right-click on the branch and select "Delete".

Note: the "Delete" option is disabled (grayed-out) for the active branch. So, you must switch to another branch before the delete option will be available.

And with that, our branch is gone:


I think I'm beginning to really like this.

Wrap Up
I started out learning Git with the command line, and I'm really glad that I did that. It gave me a good idea of how Git works, and how distributed source control behaves differently from centralized source control. And as I've used it over the last few weeks, I'm liking it more and more.

And I'm really impressed with how well Visual Studio works with Git. The built-in tools are top-notch. The thing that I like most so far is that it makes it much easier to interact with the remote repository (GitHub in this case). I see myself using the Visual Studio tools as my primary method of interacting with Git repositories. But I'll still use the command line from time to time to make sure that I don't forget how things work.

Happy Coding!

Monday, December 29, 2014

UI Considerations When Using Asynchronous Methods

Our user interface behaves differently if we use asynchronous methods than if we use synchronous methods. We need to pay careful attention to our UI when we use the "await" operator in our code.

Last time, we saw how to consume an awaitable method by using Task directly or by using the "await" operator. What we found is that it is very easy to create methods that run asynchronous code but still look like "normal" code.

You can get the code download for this article (and the previous one) from GitHub: https://github.com/jeremybytes/using-task. Articles in this series are collected here: Exploring Task, Await, and Asynchronous Methods.

[Update 09/2015: A video version of this information is available here: Basic Exception Handling.]

We're making these asynchronous method calls in a WPF application. And with the way that we left things, we've got some weird behavior that we need to deal with. Let's review the code and look at the problem.

Expected Behavior
Here's the method that we created to consume an awaitable method:


With the exception of the "await" operator, this looks pretty normal -- like code that would run sequentially on a single thread. And when we click our button, it does what we expect:

Single Button Click

But this code does *not* run sequentially on a single thread. The "Get" method runs code on a separate thread which keeps our UI thread free to process requests.

Problem Behavior
As a reminder, our "Get" method has a 3 second delay built in. So what happens if we click the button and then click the button *again* before the original method has completed? Let's try it:

2 Button Clicks

If we look at the output, we'll see that each record is in there twice: we can see "John Koenig", "Dylan Hunt", and "John Crichton". And if we scroll down, we'll see the others.

Here's a diagram of what happened in our code:


The first time we click the button, we clear the list box and then call our asynchronous method. Then if we click the button again, we clear the list box (again) and then call our asynchronous method.

After 3 seconds, the first "Get" returns, and we populate the list box with the results. Then the second "Get" method returns, and we put those items into the list box.

Fixing the Behavior
So the problem occurs because we get two sets of data back. We're clearing the list box twice, but we're clearing it *before* any of our data comes back. We could move the "ClearListBox" method below the "await" step. But that would leave our list box populated with whatever was there before while we're waiting for the data. I'd rather have the list box empty to show that something is happening (we might want to add a wait icon as well).

We could call the clear method both before and after the "await" step. But it would be better if we just prevented the user from making 2 different calls to start with.

Disabling the Button
So instead of changing how we're clearing the list box, we'll disable the button so that the user cannot click it twice.

This code is pretty simple:


We just disable the button at the top of the method and enable the button at the bottom of the method. And if we run the application, we'll see that we get the behavior that we expect:

Before Click
After Click (but still waiting for data)
Completed

Because we disable the button while we're waiting for things to complete, we can only click the button one time. This also gives a further visual clue to the user that they shouldn't try to click the button again.

Preparing for Errors
We do want to consider another situation. What if this method throws an exception somewhere along the way? With the way things are set up now, the code that re-enables the button will not get called.

We can fix this pretty easily by adding a try/finally block to our code:


Now even if we get an exception, the button will still be re-enabled.

Notice that we're treating this code exactly like "normal" code. We're wrapping it in a try/finally block, and we're relying on the compiler to take care of the asynchronous parts for us.

We'll spend a lot more time on exceptions and error handling in upcoming articles. That will include things like adding a "catch" block to this code and checking exceptions that may come back from the awaitable method.

The final code for this method is in the 06-UIConsiderations branch: https://github.com/jeremybytes/using-task/tree/06-UIConsiderations.

Fixing the Task Method
We could stop here and be happy with the results. But let's take a closer look at what's happening here. We'll do this by looking at how we would accomplish this functionality by using Task directly.

Last time, we looked at both using "Task" and using "await" so that we could get a better understanding of what's going on. We'll do that same thing here. This will give us an appreciation for what we get for free when we use the "await" operator.

Here's the method that interacts with Task:


This has the same problem as our "await" method had: if we click the button again before the original operation has completed, we end up with multiple result sets in our list box.

The simplest way to fix this is to disable the button at the top of the method and re-enable it in our continuation. Here's what that looks like:


And this works along the "happy path" (meaning nothing unexpected happens). But let's put a little bit of error handling in place.

Limiting Continuations
If we look at the documentation for the "ContinueWith" method, we'll find 40 overloads; so we have a lot of options to choose from. Our current method has the parameters of "Action<T>" (our continuation method) and "TaskScheduler" (which makes sure our continuation runs on the UI thread).

But what if the "Get" method throws an exception. We're not watching for that now. Let's assume that the "Get" method fails. That means we do not have a valid result. So in our continuation where we ask for "t.Result", we would get an exception (since "Result" is invalid).

Let's add a couple more parameters to our method:


This has 2 new parameters. First is a cancellation token. We don't really need it for this implementation, but the overload of "ContinueWith" that we want needs a cancellation token. When we create a cancellation token like this, it is always "false" (meaning, not canceled). We'll look at cancellation in an upcoming article.

[Update 12/30/2014: As Alois Kraus notes in the comments, we can use "CancellationToken.None" instead of creating a new cancellation token. This is a better way to go since we're not using the cancellation token in this instance. Check the GitHub project for the update: https://github.com/jeremybytes/using-task/tree/06-UIConsiderations.]

The other new parameter is the one we want to look at: "TaskContinuationOptions.OnlyOnRanToCompletion". This means that the continuation will *only* run if the Task operation completed successfully (meaning, no exceptions and not canceled). By including this option, we know that the Task completed successfully, and we can safely use the "Result" property of the task.

We'll look at other "TaskContinuationOptions" in future articles. This includes interesting options such as "OnlyOnFaulted", "NotOnFaulted", "NotOnCanceled", and others. Continuations are pretty flexible.

Another Problem
But now we have another problem: we are re-enabling the button inside our continuation, but the continuation only runs in a "success" state. What if we get an exception along the way?

This is the same problem that we had to consider with our "await" method. In that case, we used a try/finally block to make sure that the button was re-enabled. There are a couple of approaches that we can take here. What we'll do is create another continuation for our task:


Now we have a separate continuation that only re-enables the button. And notice that we do not have the restriction of "OnlyOnRanToCompletion". That means that this continuation will run regardless of whether the Task was faulted (i.e., an exception was thrown) or if it was canceled.

We still need the "FromCurrentSynchronizationContext" since we interacting with UI elements (the button) and we need to make sure this runs on the UI thread.

Fixed Task Method
Here's the entire method with the updated continuations:


So we disable the button at the top of the method. Then we have a continuation that *only* runs if the Task completes successfully -- this will update our list box. Then we have another continuation that *always* runs -- this will re-enable our button.

The final code for this method is in the 06-UIConsiderations branch: https://github.com/jeremybytes/using-task/tree/06-UIConsiderations.

And we get the output that we expect. Here's the disabled button after we click the button but before the Task completes:


And here's the re-enabled button when everything is done.


Again, there is some additional error handling that we can do here, and we also need to look at things like "What if the 'Get' method never completes?" So stay tuned for additional articles.

Wrap Up
As we've seen, the "await" operator lets us treat our asynchronous code very much the same as our synchronous code. This is a little dangerous because we might not think of the implications the asynchronous code may have. As we saw here, if we don't watch for it, our users can click a button multiple times and kick off multiple operations. This gives us an invalid output.

But with a little thought, we can guard against these types of situations. It's pretty easy to disable and enable buttons to prevent users from clicking them. And we saw that this is very easy to do when we are using "await". Things get a bit more complicated if we use Task directly. If nothing else, this gives us a better appreciation for the work that the compiler does for us when we use the "await" operator.

Happy Coding!

Sunday, December 28, 2014

Task and Await: Consuming Awaitable Methods

There's a lot of confusion about async/await, Task/TPL, and asynchronous and parallel programming in general. I've had some requests to dive into the topic, so we'll start with the basics and go deeper from there.

Before we look at creating our own asynchronous methods, we should look at how to consume asynchronous methods. More specifically, we'll look at how to consume "awaitable" methods. What is an "awaitable" method? These are methods that return Task or Task<T> (and they can also return "void" and there are some other awaitables, but we'll just worry about Tasks today).

You can get the code download for this article on GitHub: https://github.com/jeremybytes/using-task. Each step is in a separate branch that I'll point out as we go along.

[Update: Articles in this series are collected here: Exploring Task, Await, and Asynchronous Methods. And if you want a video version of this article, look here: Consuming Asynchronous Methods]

The Starting Library
In our application, we have several projects set up. First, we have a WebAPI project that provides us some RESTful services. Next, we have a library project that contains a repository. This repository contains an awaitable method that we want to use (from the "UsingTask.Library" project):


We won't worry about the details of this method. Today, we're just looking at how we consume this method. One thing to note is that I added an artificial 3 second delay inside this method call. This way, we'll be able to tell that our code is actually running asynchronously.

There are a couple of things to note about the "Get" method. Most importantly, this returns a "Task<T>". This means that this is an awaitable method. Since the Task has a generic type parameter, we know that "List<Person>" is the actual data that we can get out of this method.

Don't worry about the "async" keyword here. As we'll see, "async" is important for what's inside the method, but what makes this particular method awaitable is that it returns a Task.

Using Task Directly
Before we dive into looking at the "await" operator, let's see how we would consume this method by using Task directly. This will give us a better idea of what happens when we use "await".

For this, we have a WPF application (in the "UsingTask.UI" project). Here's what our UI looks like (from "MainWindow.xaml"):


We have 2 buttons to fetch data (plus a clear button), and we have a list box to hold our output.

We'll start with the event handler for the "Fetch Data (with Task)" button. This is in the code-behind for the main window.


We have a class-level "repository" field which is of type "PersonRepository". So, we'll start by calling the "Get" method on our repository. As we saw above, this method returns "Task<List<Person>>". And if we hover over the "var" keyword, we see just that:


Let's be a little more explicit with our variable type so that our code is a bit easier to read:


This gives us a Task that we can work with. Now a Task is an asynchronous operation. We can think of this as a promise -- at some point in the future, we will get a "List<Person>". But that also means we may need to wait a while before that promise is fulfilled. When we call "Get", it returns immediately. It does *not* wait for the asynchronous operation to complete.

ContinueWith
But what if we want to do something once the Task is complete? This is where we can use the "ContinueWith" method on Task. This will run code once the current Task is done with its processing.


Let's look at what kind of parameter we need for "ContinueWith". If it's not already showing, you can use Ctrl+Shift+Space to show the method signature(s).


This shows us that we need an "Action<Task<List<Person>>>". Huh?

Well "Action" is simply a built-in delegate type. For more information, you can check out one of my recent videos: C# Delegates: Action<> and Multicast Delegates. The short version is that we need a method that has "Task<List<Person>>" as a parameter and returns void.

So, we'll create that method and pass it in as a parameter to "ContinueWith".


Here we've created a new method called "FillListBox" that takes a "Task<List<Person>>" as a parameter.

The first thing we do is look at the "Result" property on our Task. The "Result" will be the "List<Person>" that we're looking for. Since we are in the "ContinueWith" method here, we know that the initial Task operation has completed, so "Result" should have a valid value (barring any exceptions, of course).

This means that our "people" variable is populated with the "List<Person>" coming back from our library. Once we have this, we can loop through the items to populate our list box.

So, let's run our application and try things out.


Uh oh. It looks like we have a bit of a problem. We're trying to populate our "PersonListBox" which we can only do from the UI thread, but apparently we're on a different thread.

With traditional threading, this is where we would use "Dispatcher.Invoke" to get things back on the UI thread. But we have a bit of an easier way of doing things here.

When we call "ContinueWith", we can give it another parameter:


This "TaskScheduler.FromCurrentSynchronizationContext()" tells our "ContinueWith" method that we want to run this "FillListBox" method on the same thread that we're calling it from (which is our UI thread since we're calling this from our button click event handler).

With this in place, our application runs as expected:


And since there is a 3 second delay in the library code, we'll have to wait a little bit after we click the "Fetch" button. But if we try to interact with the UI (for example, by moving the window on the screen), we'll see that the UI is still responsive. So we're not locking up the UI thread during this operation.

This code can be found in the "01-Task" branch: https://github.com/jeremybytes/using-task/tree/01-Task.

Using Task with a Lambda Expression
Now, I really love lambda expressions, so whenever I see "Action" as a method parameter, I want to use a lambda.

By using a lambda expression, we can inline our "FillListBox" method:


This eliminates our separate "FillListBox" method; it is replaced by a lambda expression in the "ContinueWith" parameter. You can check out Learn to Love Lambdas or C# Delegates: Get Func<>-y (+ Lambdas) for details on how to change the method call into a lambda expression.

I like this because it puts all of the code into one place (the event handler) instead of spreading it across two methods. In addition, we can use captured variables and other cool features of lambdas. (Have you figured out that I really love lambdas?)

This code can be found in the 02-TaskLambda branch: https://github.com/jeremybytes/using-task/tree/02-TaskLambda.

And even though this isn't all that difficult. There's a much easier way to accomplish this exact same task -- by using "await".

Using "await" with an Awaitable Method
Now we'll look at our second button. We'll do the same action (getting data from our repository and loading our list box), but we'll "await" things rather than deal with the Task directly.

If we look at our "repository.Get()" method, we'll see that it is listed as "awaitable", and we even get a hint on how we can use the method with the "await" operator:


This shows us that if we "await" the "Get" method, then the result will be a "List<Person>" (rather than the "Task<List<Person>>" that "Get" returns). So, "await" will wait for the Task to finish and then give us the "Result" from the "Task".

So, in our second button's event handler, let's use the "await" operator like the hint tells us:


This isn't quite what we expected. We've got red squigglies which means something is wrong. If we hover over the squigglies, it will tell us that we need the "async" keyword on the method.


Notice that once we add the "async" keyword to the method, the "await" operator is lit up (and the squigglies are gone). This is due to the way that "await" is parsed by the compiler.

"async" and "await" Go Together
The "await" operator was added in Visual Studio 2012 to leverage asynchronous support in .NET 4.5 (and Windows Runtime). The problem is that since "await" was not a keyword before, it can't magically become one since it could break existing code that is using "await" as a variable name or something else like that.

So instead, "await" is a contextual operator. The way the compiler tells the difference is whether the method is marked as "async". If the method is marked "async", then the compiler assumes that any uses of "await" refer to the context that we have here. Otherwise, it is treated just like any other identifier.

This means that "async" does not magically make a method asynchronous. All it does is tell the compiler that if it finds "await"(s) in the method, it needs to treat them with the special context that we want here.

With this in place, we can finish up our method:


Since we get a "List<Person>" by awaiting our method, we can simply continue on with our code -- looping through our person collection and populating the list box. There's no need to create a separate "ContinueWith" or make sure that we're on the right thread. The compiler handles all of this for us.

When we run our application, we'll see the same results as when we used Task directly:


During the 3 second delay, our UI is still responsive.

This code can be found in the 03-Await branch: https://github.com/jeremybytes/using-task/tree/03-Await.

Easier Code
So which would you rather write? This:


or this:


It's much easier for us to use "await". Now we only have 1 method (instead of splitting into 2 methods (even if one of those methods is a nested lambda expression)). And we don't have to worry about marshalling back to the UI thread. The synchronization context is handled for us automatically.

Even though our method with "await" is easy for us to read and write, the compiler turns it into something a bit more complex. It looks more like our manual task with the continuation (plus some other stuff). But "await" makes it very easy to consume methods while maintaining "normal"-looking code.

Limitations with Async
There are a few limitations when we use the "async" keyword. The main limitation is with our return type. When we mark a method as "async", we must have one of three return types:
  • Task
  • Task<T>
  • void
If we have anything else, then we'll get an error. And we have to be careful if we return "void" because we lose visibility to any exceptions that might happen during the asynchronous operation. In addition, we won't know when that operation has finished.

If we have a Task, then we can check the status, get notified of faults, and look for exceptions. We'll look at all of this in an upcoming article.

A Console Application
Let's see what happens when we run into one of these limitations. For this, we'll try to use our same library in a console application. Here's our starting point (in the "UsingTasks.Tester" project):


So let's add our awaitable method call:


This shows the error around the "await" operator like we saw earlier. This means that we need to add "async" to our method:


But we still have a problem. "Main" isn't happy. Here's the error message:


Now what? We're not allowed to use "async" with the "Main" method in our console application.

But all is not lost. We can still get some benefit out of this library. Remember in our "FillListBox" method where we checked the "Result" property on the Task?


We can do that in our console application:


Since "Get" returns a Task, we can directly check the "Result" property. When we do this, we get the output that we expect (mostly):



This code can be found in the 04-Console branch: https://github.com/jeremybytes/using-task/tree/04-Console.

Danger Danger Danger
Now why did I say "mostly"? It's because we broke the asynchrony here. When we check the "Result" property, our thread will wait for the "Result" to be populated. This means that our application is hung during this operation. So when we have the 3 second delay in our library, our application will stop responding.

Our other option would be to use the "ContinueWith" method on the Task like we did above. And this is generally what we want to do. When we use "Result", we need to be aware that it could lock up our application.

Using ContinueWith in the Console Application
[Update 12/28/2014: I decided to add the code for using "ContinueWith" in the console application. This code can be found in the 05-ConsoleContinue branch: https://github.com/jeremybytes/using-task/tree/05-ConsoleContinue.]

If we don't want our console application to lock up during the 3 second delay, we can add a continuation to the Task like we did with our WPF application. Here's our updated Main method:


Instead of using the "Result" immediately, we get the Task from our "Get" method (just like above). Then we use the "ContinueWith" method to put in the code that we want to run when the task is complete.

In the "FillConsole" method, we get the "Result" from our Task (which is now complete, so we're not locking up any threads), and then we loop through the list and output to the console. If we wanted, we could convert this to a lambda expression like we did above, but I'll leave that as an exercise for the reader.

Notice that we do not have "TaskSchedule.WithCurrentSynchronizationContext" like we had in our WPF application. That's because we don't need it here. We can write to the Console from whatever thread we like, so there is no need to get back to the main thread. (If we did need to run this code on the  main thread for some reason, that's where things get a bit interesting. But we won't worry about that today.)

Just to show that we are not locking up our thread, I added the "for" loop to output the numbers 0 through 4 to our Console. If we run the application, we'll see that these numbers output immediately (they don't wait for the Task to complete). Then after 3 seconds, we get our normal output:


This shows us that we are getting the asynchronous behavior that we expect.

Wrap Up
So this was a whirlwind tour of consuming an awaitable method. We saw how we could use the Task directly and manually create a continuation. Or we can use the "await" keyword and let the compiler generate that continuation for us. By seeing how to do thing manually, we get a better appreciation for the automation that the compiler gives us.

We'll look at related topics in upcoming articles, including error handling, creating our own awaitable methods, and looking at situations where our methods may sometimes run synchronously even if they are awaitable.

It takes a bit of time to wrap your head around this topic, so feel free to send me any questions on what I've covered here (as well as topics you'd like to see covered in future articles). We'll work in small steps to get a good understanding of what goes on in the world of asynchronous programming.

Happy Coding!