Saturday, December 31, 2016

2016 Year in Review

It's been an interesting year. I've traveled quite a bit, met a lot of great people, made some friends, and learned some new things.

Note: This article is primarily for myself. It's for me to review my year and see what kind of progress I've made compared to previous years. I recommend that you do the same. Compare yourself to yourself last year. Do not compare yourself to me.

Travels
I did quite a bit more traveling this year compared to last year. I was away from home for 95 days (and my cats weren't too happy about me being away that much). But I got to see a lot of new places:

2016 US Travels
2016 European Travels

Fortunately(?) Google has been tracking me all year, so it was pretty easy to get these maps.

I was on lots of airplanes this year (okay, so it was 41 airplanes). A side-effect of that is that I got Silver status on United in April and then Gold status in October. I've also got to know the Denver and Houston airports pretty well.

And even though there are dots on the map for Stockholm and Copenhagen, those were just airport changes (although I did get to learn what a French hot dog was while I was in Copenhagen).

Speaking
I had a really great time speaking this year. I spoke at 35 events - a mix of user groups, corporate events, code camps, regional events, and professional events.

User groups are great because it gives us lots of time with a topic. It's also a bit less formal, so we can dig into questions and have a good conversation. I spoke at 16 user groups, mostly .NET-related since that's where most of my technical talks live. But I also spoke at a couple agile-related groups as well.

I managed to make it to 3 code camps this year. Code Camps are great because they give developers a great chance to get tons of free information all in one place. It's also a great place for developers to get started as speakers. Unfortunately, I didn't get to either of the So Cal Code Camps this year; I had conflicting events. I'm going to try to make it to them in 2017.

My biggest change this year was speaking at regional events. These are great opportunities for developers to get some great information for a lot cheaper than a professional conference. I spoke at 7 regional events (up from 2 last year).

One really cool thing is that I was asked to keynote at AIM/hdc. I had a really great time doing this.

I had the chance to speak at 4 professional events (including 2 outside the US). This was great particularly since I spoke at my first professional conference late last year.

Workshops
I got to expand into something new this year: full-day workshops. This gave me a chance to get into a bit more detail and also engage with folks a lot more. I did 4 workshops, and each was a bit different. The groups ranged in size from 4 to 35. Some people worked together, some were complete strangers. And I got to work with developers with different levels of experience.

I'd like to expand to do more workshops. And I've learned quite a bit from my experience this year. One challenge is that some venues want a majority of lecture and some venues want a majority of labs. I'll have to plan for a lot of flexibility so that I can get the right mix for a particular group.

Note: if you're trying to get the numbers to add up, it doesn't quite match up. That's because there's a bit of overlap for some of the events/workshops. If you're curious, you can check the list of all of the events on my website.

Recognition
I've been meeting more and more people at events who know me through Pluralsight or podcasts or my blog. A big reason why I've been speaking so much (other than I really love to do it) is to help build my brand and get more recognizable.

Here's the best comment that I've received this year (from someone at Music City Code):

"You are a lot taller than you seem on Pluralsight."

Get Your Request In
If you'd like me to come to speak at a particular event, send me a request. There are too many good events to make it to all of them (and I think I traveled just a little too much this year), so I'll have to make some tough choices. If someone puts in a request, it will go to the top of the list.

Consulting
I did a bit less consulting work this year than I did in 2015. I haven't been pushing this much, but it's something that I really love to do.
I don't want to write your code;
I want to make it so your developers can write your code.
I really enjoy helping people in this area. Many times, I'm working with a small team of 2 or 3 developers who don't have an expert in their group. The problem in that scenario is that you don't know what you don't know.

I've had a chance to help out these teams by doing a code review and looking at the pain points that they have. Based on that, I can give guidance on technology and techniques that can help them improve their situation. And if they aren't familiar with those techniques, it gives me a chance to do some teaching.

And that's what I really love to do: make developers better.

I'll be looking to expand this work in 2017.

Streams & Podcasts
I've had several people ask to be part of their streams and podcasts this year. Dave Rael invited me to come back onto the Developer On Fire podcast, Scott Nimrod invited me to have a conversation about programming where we talked about all sorts of stuff, and Steve Bishop invited me to show some of my experience (and problems) with TDD.

I really enjoyed these opportunities because I get to be part of conversation where we can bounce ideas off of each other.

Becoming a Social Developer
There have been some great opportunites for me to share "Becoming a Social Developer" this year. At NDC Oslo, they gave me a full hour to talk about it. It went much better than expected, and I was happy to see the positive response.

"Becoming a Social Developer" at NDC Oslo
I also got the chance to share a bit at Code PaLOUsa in Louisville, KY. A big thanks to them for giving me 10 minutes to share.

Also, a big thanks to David Neal (@reverentgeek) for giving me some time during his keynote at Music City Code in Nashville, TN. That was another great opportunity for me to share (and get some great pictures from the event photographer).

"Becoming a Social Developer" at Music City Code

As already mentioned, Dave Rael invited me back to Developer on Fire to specifically talk about "Becoming a Social Developer". And at AIM/hdc, they requested that I include the topic as part of my keynote presentation.

I'm still amazed at the reaction to "Becoming a Social Developer". It really resonates with quite a few people. I have some opportunities coming up in 2017 to share (including SDD 2017), and I'll be looking for others as well.

Friends
One really great thing about all the travel this year was that I got to meet a lot of great people. In addition, most of the regional events that I spoke at were in the same part of the country. This meant that I got to spend time with the speakers who were making the circuit. At each event, it seems like I got to know one or two people really well. You can read a bit more about it in an article I wrote earlier this year.

I didn't realize how large my circle of friends had grown until I went to the Microsoft MVP Summit in November. I felt like I knew twice as many people as I did the previous year, and this was just from people I had talked to at various events. I spread myself a bit thin at the summit since I wanted to spend at least a little bit of time with everyone that I knew.


And this was just from folks who were at the Microsoft MVP Summit. A lot of the friends I've made were not there. It really made me think about just how big my circle has expanded this year. It's an interesting experience for someone who is not typically a social person.

Videos & Blog
Because of all the traveling, I haven't spent as much time with videos and blogging. (I'm really amazed at how exhausting traveling can be.)

My YouTube channel has been a bit dormant. I published 4 videos this year (compared to 10 last year).

My blog has been a bit down as well. I published 74 articles, including this one (compared to 86 last year). I did have some good series on Euler problems, learning F#, unit testing, and asynchronous programming. In addition, I found myself writing quite a bit about how to help other developers and what we can do to improve the culture of our industry.

Learning
I've learned quite a bit this year. Most of what I've been experimenting with has turned into blog articles, so the list looks pretty similar to what I wrote above: learning F# (using Euler problems), unit testing and TDD, asynchronous programming, and more.

This coming year, I'd like to expand more into machine learning, and I feel like I need to look at containers (like Docker). To go along with the machine learning, both Azure Functions and AWS Lambda look really interesting.

I haven't looked at .NET Core much at this point, primarily because I don't usually do much with pre-release technology. Once it releases (along with the tooling coming with Visual Studio 2017), I'll be looking at it a bit closer.

A great side effect of speaking at so many events is that I'm also attending those events. This has given me a chance to hear great speakers talk about a variety of different technologies. I don't know how many of them will become part of my regular development, but it's important to know what they are good for. Then I can take a closer look when the right problem comes up.

Being Human
A lot of the conversations that I've had with other developers this year have not been about technology. They have been about being human. This is something that is really easy to ignore or suppress in our industry, but it is a very important area. We learn about ourselves, we learn about the people we work with, we learn about the people that we build software for.

I'll be exploring this topic a lot further in the coming year.

Coming in 2017
I'm not quite sure what's coming for me in 2017. I don't have a list of goals for the year. There are times that I feel like I'm living life a bit by accident. But I've also found that the things that I run towards usually don't work out, and that better opportunities come up that I haven't planned. (And for those of you who are curious about my high risk decision, I'll be giving an update in the next couple weeks.)

With that said, I'm heading in a general direction. I don't know exactly which path my journey will take, but I know that it will be an interesting one.

Remember, in the coming year, don't compare yourself to those around you. We all take different paths, and those comparisons are not valid. Compare yourself to yourself in the past. And use that to improve yourself going forward.

Happy Coding!

Tuesday, December 27, 2016

More Simple Mocking in F# with Object Expressions

A few weeks ago, I did some simple mocking in F# by using object expressions. I thought this was a really cool option, particularly since most of my mocking requirements have been pretty simple. I ended up doing some more experimentation and found a couple more things that work great in simple scenarios.

So today, we'll look at how we can provide different results based on different parameters and how we can count the number of times a method is called.

As a side note, I have been doing some experimentation with Foq (I use Moq pretty extensively in the C# world). Unfortunately, I've been failing at the implementation; my F# skills need some work. Once I get that figured out, I'll show how that is better option when dealing with more complex scenarios. [Update 12/30/2016: It looks like my issues are related to the test runner, not my F# skills. More to come.]

[Update 1/4/2017: It turned out to be a runtime version issue. Read more here: Trying to Get Foq Working with NUnit Test Runners.]

Simple Method Mocking
In the last article, we looked at mocking using a simple object expression:

Simple Method Mocking with an Object Expression

This scenario is pretty simple. We have an interface (ISolarService) which has a single method (GetServiceData). The object expression (inside the curly braces) allows us to specify that if anyone calls the "GetServiceData" method, it should return the results in our "goodData" object (this is just a string with JSON data that's specified at the top of the test class).

Date/DateTime Functions
I made another change to the code since we looked at it last time. Notice that the test function above has calls to "date" and "dateTime". I created these functions to adjust the syntax a bit. Previously, I was creating DateTime objects directly, and the code looked like this:

Code with Original DateTime objects

I played around with syntax a bit and came up with these two functions:


These functions wrap a call to the DateTime constructor. I'm not sure if I'm 100% happy with this, but I do like how things look in the calling code when we call "date" and "dateTime". It seems to fit in better with the F# style.

Along with this, I added the intermediate items "requestDate" and "expected". By adding these, I could eliminate the parentheses later on. Again, I'm not sure if this is a good way to go, but I do like the syntax a bit better here.

Different Parameters, Different Results
While I was exploring mocking, I ran across a sample that showed a really easy way to have different result sets returned from a method based on the parameter. (Sorry, I didn't keep track of the article, so I can't point back to it.)

To have different result sets come back, we can expand our object expression to use pattern matching in the body of the member:

Simple Method Mocking with Pattern Matching

In this code, we don't ignore the parameter. Instead, we grab onto it so we can match against it.

So if we pass in the "requestDate" (which is Nov 24th 2016), we return our "goodData" string. But if we pass in any other value, we return our "badData" string.

This is strictly not necessary for this particular test, but if we had a shared mock object, it could be useful in providing different results for different tests or parameters. (It would also be useful for property-based testing, but that's a topic for another time.)

So we can expand our object expression to be a bit more flexible. And it doesn't take much code to do this (and that makes me happy).

Counting Method Calls
Another area where I've used mocking is to count the number of times that a method is called. This is primarily to check to see if a client-side cache is working, i.e. multiple calls to the client method should only result in a single service call.

With Moq (and Foq), we can do this by using the "Verify" method. And I've done this quite a bit with Moq in my C# code. For a simple scenario (like we have with the Sunrise/Sunset library), we can do the counting manually with just a little bit of code.

Here's an example:

Simple Method Call Counting

Each time the "GetServiceData" method is called, we increment the "callCount" variable. To test this, we call "GetSunset" twice with the same parameter. We don't care about the results of those method calls, so we just ignore them.

But then we check the "callCount" to make sure that the service method inside our mock object was only called one time.

Here's a test that shows something similar:

Simple Method Call Counting

In this case, we call "GetSunset" with different parameters, so we expect that the service is called twice.

There are a couple things I'd like to change about this code. I would like to have the counter (callCount) be part of the object expression. In the current state, it seems to "leak" since the counter is completely separate from the object.

Another thing about this code is that it only works with a single method. If the mock object had multiple members that we wanted to track, then things would get quite a bit more complicated.

I'm sure that I could write that code, but what I'd really be doing is writing my own mocking framework. And that's something I definitely don't want to do. I'd rather leave that to the experts who have already done this.

Mocking Frameworks
These examples work great with very simple scenarios. In this case, we only have a single method in the interface. But as soon as we have multiple methods, it's pretty common to only want to provide mock implementations for only one or two of them. In addition, we may want to track calls to multiple methods. That's where our code breaks down.

I've taken a quick look at Foq (and even Moq) in my F# tests, and that's where I found that my F# skills are still lacking. I seem to be doing okay at compile time (everything builds), but I'm getting errors at run time. So I need to figure out where I'm going wrong. I'm pretty sure it's around the code quotations. Once I get that worked out, I'll do some more exploration and write up my results.

[Update: 12/30/2016: It looks like the problems I've run into with Foq are related to the test runner that I'm using and not because of my F# skills. I can get test code to run in the REPL, but I get exceptions with using the NUnit test adapter. I've got a bit more to figure out here.]

[Update 1/4/2017: It turned out to be a runtime version issue. Read more here: Trying to Get Foq Working with NUnit Test Runners.]

Wrap Up
The more I work with it, the more I like the idea of using F# for testing my C# code. Unit tests are generally functional in nature: discrete inputs/outputs, no side-effects. So it seems like a good fit. Plus it gives me a chance to get better at F# using small steps.

One thing about being a programmer: it's impossible to get bored.

Happy Coding!

Monday, December 19, 2016

When Progress Reporting Goes Bad: Incremental Progress vs. Cumulative Progress

Last time, we looked at how to report progress with an asynchronous task by using whatever payload we like. For that example, we used cumulative progress reporting, where the asynchronous method reported back on how far along it was in the process. This worked for our example, but if we try to add some parallelism to our asynchronous process, we run into problems.

The idea behind incremental progress reporting is that we just report increments from the asynchronous process, and we leave the aggregation up to the calling code.

Note: this article is inspired by Stephen Cleary's article on Reporting Progress from Async Tasks (specifically look at the section "Defining 'Progress'"). Stephen is a great resource for all thing async, so be sure to check out his articles and his book.

Let's take a look at our current solution, see the problem when we add some parallelism, and how we can fix our reporting by thinking incrementally.

Cumulative Progress Reporting
The way we left our code in the last article is using cumulative progress reporting. Here's what the reporting looks like:

Cumulative Progress Reporting

If we look at the output, we see that the numbers count up in order, from 1 to 7. Some of the number blip by pretty quickly, but they are all there.

The code comes from the 10b-CustomProgress branch of the GitHub project: jeremybytes/using-task.

The values are coming from the progress report itself. As a reminder, here is the code that reports the progress:

Reporting Progress (Original)

This uses a "for" loop to iterate through the items in our collection. The "Report" method is what we want to pay attention to here. This sends back at "PersonProgressData" object that has 3 pieces: (1) the item number, (2) the total number of items, and (3) the name on the item.

Since these are processed in order and reported in order, things come out in the right order on the UI side as well. So we can simply put these values into a string:

Showing Progress (Original)

We're letting the asynchronous method handle the aggregation (meaning that it's telling us how many items have been processed). This is what Stephen refers to as "cumulative" progress reporting. And it works fine as long as things stay in order.

But when we're talking about asynchronous code, things don't always happen in order.

The Problem: Parallelism and Cumulative Reporting
As long as we're doing async coding, we might as well add some parallelism as well. Right now, we're "processing" items one at a time. What if we create some more asynchronous tasks so that we can process multiple items at one time?

That's where we run into problems. Let's see our output with some parallel processing:

Cumulative Progress Reporting (with parallel processing)

Yikes! Our items are reported out of order now: 6, 5, 2, 7, 1. We don't see all of the items reported because we have a couple items that are reported "at the same time" (or at least close enough together that we don't see the UI updates).

Think about the chaos this would cause if we had this hooked up to a progress bar. It would be jumping all over the place. It's particularly bad since it ends with "1 of 7" in this case rather than starting with "1 of 7". At the end, our progress bar would show "14%".

If you're curious to see this code, you can check out the 10c-IncrementalProgress branch.

The asynchronous method has been updated to look like this:

Reporting Progress (with parallel processing)

This code has a few kludges in it since we're not doing real processing. Inside the "for" loop, we create a new Task for each of our items. The "Thread.Sleep()" is a kludge to make sure that the tasks don't all finish so close together that we can't see the reporting.

After the "Thread.Sleep()", we do that same thing as we did before: check the cancellation token and then report the progress.

We add each task to a collection so that we can use the "WhenAll" method on Task. When we "await" this, our code won't move forward until all 7 of our tasks are complete.

This code is not a recommendation for creating your own parallel tasks (for that, you can check out the processing that I've done in the Digit Recognizer project). This code just helps us see one of the problems we run into when we add parallelism.

Incremental Reporting
To fix this code, we won't rely on the asynchronous process to tell us where we are in the process. Instead, we'll just use it for incremental reporting -- to tell us that one more item is complete. We'll keep a counter on the client side to handle the aggregation.

Here's the result:

Incremental Progress Reporting (with parallel processing)

Notice the difference here. We can see our progress increasing "2 of 7", "3 of 7", "5 of 7", "6 of 7", and "7 of 7". (The "1" and "4" blip by really quickly.)

The number in parentheses is the item number. So it ends with item #2 (Dylan Hunt), but since we're keeping the actual completed count on the client side, our progress is in the right order.

I made a couple changes to the client-side code to accommodate this. These are in the "MainWindow.xaml.cs" file (the code-behind of our form).

First, I added a "count" field that we could use as an accumulator. This is at the top of the class:

"count" Field

The next trick is that we need to have the "count" reset to 0 each time we kick off our asynchronous method. I handled this by getting rid of the class level "IProgress<T>" object that we had in our last example.

Instead of creating our progress object in the constructor of our class, I added a factory method that would reset the counter and create the IProgress:

Factory Method for IProgress

The important bit of the updated string is that we are using the "Item" property for reference only. To keep track of actual progress, we're using the "count" field.

With regard to the "count" field, notice that we set it to 0 at the top of the method, then we increment it inside the delegate that gets called when progress is reported. (We use the pre-increment operator (with the "++" before "count") so that it will increment the value before it's printed out.)

We still need to pass the "IProgress<T>" to the "Get" method like we did before. But instead of using the class-level field, we use the factory method:

Passing the IProgress as a Parameter

When we put all of these pieces together, we get progress reporting that shows the actual progress (even if the items are not reported "in order").


If we were to hook this up to a progress bar, we would get a nice increasing progress that would show "100%" at the end.

Threading Concerns
As mentioned in previous articles, we do need to be careful about where we create the progress objects. Since we want the delegate to run on the UI thread (because we're interacting with UI elements), we need to make sure we create the progress object on the UI thread. (See "Pay Attention to Where You Create Progress Objects" for more information.)

In this case, we're calling the factory method (GetFreshProgress) as a parameter to the "Get" method. This will be resolved on the current thread before the "Get" method is called. So our progress object will be created in the right spot. This is how we can safely interact with the TextBlock on our UI.

Next, we might be concerned about the "count" field since it's shared state that we're incrementing in our delegate. But in this case, the delegate is running on the UI thread (as mentioned above). So even if progress is reported "at the same time", the delegates will only execute one at a time since it runs on the UI thread (and the UI thread will only do one thing at a time). So we don't have to worry about race conditions here.

As a side note, we could move "count" to be a method-level variable in the factory method. Since it gets captured by the delegate, things would still work as expected. I might do that in the final project code. For more information on captured variables, see Lambda Expression Basics.

Wrap Up
By using incremental progress reporting, we don't care what order things are processed or reported on the asynchronous side. Instead, we do the aggregation on the client side before we report the progress. This ensures that our progress is always moving in the right direction.

When we start talking about asynchronous and parallel processing, things get really interesting. It's easy to get things "out of order". And even better, things will process differently based on the number of cores on a particular machine. (It's really interesting to watch the Digit Recognizer max out the CPU by using all the cores on the machine.)

So we do need to put a little bit more thought into things. But once we get in that mindset, things become a bit easier. And if we use functional-style programming that doesn't use shared state, then running things in parallel gets a lot easier.

Happy Coding!

Thursday, December 15, 2016

Custom Progress Reporting with Task

Last time, we looked at how to do simple progress reporting with Task. In that example, we passed an integer from our asynchronous method to the calling method. This time around, we'll use a custom reporting payload. This will let us pass along any information we want.

For this, we'll show information as each record in our dataset is "processed". Here's the output:

Application w/ Progress Reporting

The text shows us the progress. "Processing 6 of 7" tells us which record we're on and how many there are total. And "Dante Montana" tells us some details about the current record.

So let's see how we can get this data from our asynchronous method into the calling code for display.

Reporting Progress with Task
Just like we saw last time, we'll use the IProgress<T> interface. But instead of using an integer, we'll use a custom object (which we'll call "PersonProgressData"). The steps for using this are pretty much the same as we saw before.

Just like with our previous example, we'll start with the code that was used in prior Task articles: GitHub: jeremybytes/using-task.

This time, we'll be looking at branch 10b-CustomProgress.

Let's see what we need to do to add this custom progress to our application.

Adding the Custom Reporting Object
First, we'll create the custom object that will hold our reporting payload. For this, we'll have 3 properties: the current item number, the total number of items, and the name on the current item.

I've added a new class to the top of the PersonRepository.cs file:

Custom Progress Reporting Class

Here we have 3 read-only properties and a constructor to populate the values.

Updating the Asynchronous Method
We use the IProgress<T> interface to get things to work. So we'll create a parameter of that type in our asynchronous method.

Here's the updated "Get" method of the PersonRepository class (PersonRepository.cs):

Updated Method Parameters

Notice that we're using our custom type (PersonProgressData) as the generic type parameter.

To use this in our code, I've modified the method itself a bit. First, we had an artificial 3 second delay at the top of the method (this was to help us see the asynchronous process in action). I've removed that for this example:

Delay has been removed

Next, I made some modifications to the code before it returns the data. In the original code, we returned the data directly from the service. This time, we are going to "process" the data before returning it. Here's that block of code:

Reporting Progress

Rather than returning the result of the "await", we store it in a variable we can use. Then we use a "for" loop to iterate through all of the records. This is where we "process" the data. We're just simulating that.

First we check our cancellation token. Inside a loop is a great place to check for cancellation. This allows us to short-circuit the processing.

The next step is to report the progress. We do this with "progress?.Report()". The "Report" method will take our custom object as a parameter, so we need to new up an instance of the "PersonProgressData" class with the appropriate values.

One other thing to note is that we're using the null-conditional operator (?.) here. If the "progress" object happens to be null (due to the parameter), then nothing will happen (and we also won't get a NullReferenceException). If the "progress" object is not null, then the "Report" method is called.

The last step is to delay for 300 milliseconds. This simulates our processing and gives us a chance to see the values updating in the UI as progress is reported.

The result is that we'll get a progress report for each item in our dataset.

Note: If you try to compile the code now, you'll get a bunch of errors since we added a new parameter. You can update the calls to the "Get" method by adding a "null" parameter, and the code will work just like it did before.

That takes care of progress reporting from the asynchronous method, now let's see what changes we need to make to the calling code.

Updating the UI
The UI needs to be updated to give us a spot to report the progress. We'll add a text block to our existing WPF form just like we did when we reported simple progress in the prior article. Here's the XAML (from MainWindow.xaml):

UI Elements for Progress Reporting

Now that we have this spot in our UI, we just need to update the calling code.

Updating the Calling Code
We need an implementation of the IProgress<PersonProgressData> interface. We'll start by creating a class-level field to hold this object. This will be in the code-behind of our form (MainWindow.xaml.cs):

IProgress<T> Field

By having a class-level field, we can share this object between our various method calls.

But now we need an object that implements this interface. Fortunately, we can use the built in Progress<T> object. The constructor for Progress<T> take a delegate as a parameter. This delegate is the method that we want to run when progress is reported.

The delegate needs to return void and take a "PersonProgressData" object as a parameter. In the last example (with the simple progress), we used a separate named delegate. Here we'll use a lambda expression instead.

Here's what our constructor looks like now:

Creating the Progress object

Let's take a closer look at the lambda expression. The "d" is our parameter and represents the "PersonProgressData" object (I used "d" for "data").

The body of the lambda expression sets the value in our text block. This is a string that uses the "Item" (number of the current item), "Total" (total number of items), and "Name" (name on the item) that comes from our custom reporting object.

Note: If you want to get a better understanding of lambda expressions, take a look at Learn to Love Lambdas (and LINQ, Too!).

Adding the Parameter to the Calling Code
The last step is to add the class-level field as a parameter in the calling code.

Here's the updated call in the "FetchWithTaskButton_Click" method:

Updated "Get" Call

We just added "progress" as a parameter to the "Get" method call. This code looks exactly the same as the code we saw with the simple progress reporting.

The result is that we get the progress reported in our UI:


To update the call where we use "await", things look very similar. Here's the code from "FetchWithAwaitButton_Click":

Updated "Get" Call

This will give us the same type of progress reporting when we use the "await" button.

Where To Go From Here
We've seen how we can pass whatever we like for progress reporting. We can use a built in type (like "int") or we can create a custom type that will hold whatever values we need (like "PersonProgressData").

Showing Progress
We also have a lot of freedom on how we handle things in the UI. Here we just updated a text block. But we could just as easily hook things up to a progress bar or simply display a status message. Concepts around progress reporting get interesting once we start diving in a bit deeper.

Incremental Progress Reporting
Something else to think about: we might not process the items in order. For example, rather than "processing" in sequence, we could kick off parallel tasks to process the items. In this case, having an item number might not make sense because the actual order could be different based on the task scheduler. Stephen Cleary recommends doing "incremental" progress reporting rather than "cumulative" progress reporting. This makes a lot of sense in asynchronous environments. See the "Defining 'Progress'" section of his article for more information.

Update: I wrote an article on how adding a bit of parallelism completely destroys our example. But it can be fixed by using incremental reporting: When Progress Reporting Goes Bad: Incremental Progress vs. Cumulative Progress.

Thread Warning
One last warning. There are some subtleties regarding where we create the Progress<T> object. In our code, we're updating UI elements, so we need the delegate to run on the UI thread. Since we're creating the Progress<T> object on our UI thread, things work as expected. It's tempting to create this object in a different spot in the code. If we're not careful, we could end up with unexpected behavior. For more information, take a look at this article: Pay Attention to Where You Create Progress Objects.

Reporting progress is always lots of fun. For more information on Task and await, check out the resources available here: I'll Get Back To You: Task, Await, and Asynchronous Methods.

Happy Coding!

Simple Progress Reporting with Task

Last week at Live! 360 Orlando, I got to give one of my favorite talks: I"ll Get Back to You: Task, Await, and Asynchronous Methods. Afterwards, I had a couple people ask me about reporting progress, and that's when I realized, I didn't have any articles to point to about it. So, it's time to correct that.

Today we'll look at reporting progress using just an integer value. In the next article, we'll see how we can create our own custom payload to use as part of progress reporting.

We'll just create a simple countdown while we're waiting for the data to return:

Application w/ Progress Reporting

The "Countdown to Data: 2" is our progress item.

Note: Yes, I realize that this is an overly simple example, but we'll be able to see the progress reporting in action. We'll look at a more useful example a bit later.

Reporting Progress with Task
The good news is that we have an interface we can use for progress reporting: IProgress<T>. The generic type parameter is for the payload that we're returning. The interface itself has only one member: Report. As you might guess, this is used to report progress.

On the consumer side, we give our progress object a delegate that will get called whenever the Report method is called in the asynchronous process.

So let's see how this will works. For this example, we'll start with the same code that was used in prior articles. The GitHub repo is here: GitHub: jeremybytes/using-task

Specifically, we'll be looking at a branch: 10a-SimpleProgress.

We'll only modify 3 files to get this work.

Updating the Asynchronous Method
We need a way to get the progress object into our asynchronous method, so we'll add a parameter. As noted above, we just need to add a parameter of type IProgress<T>.

This code is in the "PersonRepository" class (PersonRepository.cs):

Updated Method Parameters

For this example, we're going to report an integer value back to the calling code, so we have are using "int" as the generic type parameter.

Then in our code, we just need to call the "Report" method whenever we want to send something back to the caller. We're keeping things really simple here (we'll get a bit more complex in the next article).

Our original code has a 3-second delay in the code. This was to demonstrate the asynchronous nature of the method calls; we could still interact with the UI while waiting for the asynchronous process to complete. For this example, we'll split that 3-second delay into 3 separate 1-second delays. Then we'll report progress on each one by creating a simple countdown.

Here's what the updated code looks like inside our "Get" method:

Reporting Progress

We are reporting progress 3 times in this case. As you can see, all we need to do is call the "Report" method on our progress object and then pass in the value we want to send back -- in this case an integer.

I'm using the null conditional operator (?.) just in case the calling code does not pass in a valid progress object (we'll look at the calling side in just a bit). If "progress" is null, then nothing happens: "Report" is not called, but we also won't get a NullReferenceException. If "progress" is not null, then the "Report" method is called with the specified payload.

Note: If you try to compile the code now, you'll get a bunch of errors since we added a new parameter. You can update the calls to the "Get" method by adding a "null" parameter, and the code will work just like it did before.

Now let's see what we need to do to the calling code to use this.

Updating the UI
The UI needs to be updated to give us a spot to report the progress. In this case, I simply added a text block to our existing WPF form. Here's the XAML for that (from MainWindow.xaml):

UI Elements for Progress Reporting

This is a pretty simple change. It's mostly about positioning and sizing. But now we have a spot to put our progress message.

Updating the Calling Code
This is where things get interesting. In our calling code, we need an implementation of the "IProgress<int>" interface. We'll start by creating a class-level field to hold our progress object. This is at the class level because we'll share the same progress reporting across our methods.

Here's the field added to the code-behind of our form (MainWindow.xaml.cs):

Field for our Progress object

Now we need an object that implements the "IProgress<int>" interface. Fortunately, there is a built in "Progress" type that implements this interface.

The constructor for the Progress<T> type takes a delegate parameter. This delegate is the code that we want to run when the "Report" method is called. The delegate takes a parameter that matches the generic type parameter ("int" in our case), and this is how we get access to the payload.

For our code, we'll create the Progress object in the constructor, and we'll have a separate delegate that performs the work:

Creating the Progress object

In the constructor, we create the "Progress<int>" and pass in the "ReportProgress" method as a parameter. Then we assign the result to our class-level field.

The signature for our delegate (ReportProgress) is important. Notice that it returns void and takes and integer as a parameter. The parameter has to match the generic type parameter of the Progress object.

Then we can use that parameter value to update our UI. In this case, if it's not zero, we put "Countdown to Data" in our text block. If it is zero, then we clear out the text block.

Using the Progress Object in the Calling Code
The last step is to use the progress object in our calling code. For this, we simply need to pass our "progress" field as a parameter to the "Get" method.

Using Progress with Task
Here's the updated code from "FetchWithTaskButton_Click" where we are using Task directly:

Updated "Get" Call

When we call the "Get" method, we just pass in our "progress" object (in addition to the cancellation token that was already there).

With this code in place, we get progress reporting in our UI. Again, this is a pretty simple example, but it is not difficult to do.


Using Progress with Await
When we're using "await" (rather than interacting with Task directly), we can do progress reporting the same way. All we need to do is add the "progress" parameter to the "Get" call. This is from the "FetchWithAwaitButton_Click" method:

Updated "Get" Call

With this in place, we get the same progress reporting when we use "await".

One Last Update
There is one other update to this code: when we report a progress of "0", then the text block is completely cleared out. In order to accomplish this, we call "Report(0)" just before returning the result set from our asynchronous method:


This way, when our data has returned, our UI will not show progress (since it's done):

No Progress Showing (Completed)

There's More
This shows us some very simple progress reporting. In the next article, we'll look at sending back some more information. For example, if we're processing a bunch of records in the asynchronous process, we might want to let the caller know which record we're on and how many are left to process. We can easily do this by creating a custom type to use as our progress payload.

And there are also some subtleties about where the progress delegate runs. Since we're interacting with UI elements, we want to make sure that our delegate runs on the UI thread. That works with the way we have things here, but if we create things a little differently, we can get into trouble. For more information, check out this article: Pay Attention to Where You Create Progress Objects.

Wrap Up
The basics of progress reporting when using Task aren't that complex. Most of the time, we're trying to figure out whether we can actually report progress (it's hard to report progress on a database or service call).

With the IProgress<T> interface along with the built in Progress type, we can get progress reporting up and running pretty quickly. Next time, we'll look at a more complex payload. Until then...

Happy Coding!