Archive for October, 2011

FYI – I am only scratching the surface on this topic here. So, things I say in this post may be questionable .. just trying to understand asynchrony better by writing stuff down & gathering some feedback. You’ve been warned :)

Ever had to do asynchronous programming? Yeah, that thing which is the right thing to do, but just not very easy syntactically. Well, join the club as you are not alone. For ages, we have written callback after callback trying make stuff asynchronous, in the process, muddying up code readability. So, it is enlightening to see Microsoft acknowledging this & trying to have our compilers do some heavy-lifting around asynchronous programming. The goal is to abstract away some of the complexities of wiring up callbacks, so that our asynchronous programming code looks similar to the sinful synchronous code. This, if effective, will be a nice addition to the developer arsenal, specially in this age of smartphones & tablets where locking up the UI is just not an option. So, let’s dig in some, shall we?

Just to be clear .. we are talking about asynchrony here, and not parallelism! Asynchrony, simply put, is the mechanism of inter-weaving computational operations so that threads aren’t locked up. Parallelism, on the other hand, means spinning up new threads/processes, mostly to take advantage of additional computational cores. Parallelism is a difficult beast by nature & I hear things get very complex quickly. Asynchrony may be tackled with some coffee, and might have a silver bullet, as we are about to see.

The added focus on asynchronous programming was revealed in the Async CTP release at the end of 2010 .. find out more details here along with some great demos/videos. And now, the same features are becoming a lot more mainstream. So, I have been playing with C# 5.0 on top of .NET 4.5 inside Visual Studio 11 preview for Windows 8 Dev Preview .. phew, lot of CTP stuff in that line! So, I understand a lot of this might change & there is inadequate tooling support in some cases. But the asynchronous programming enhancements had me intrigued. What followed was a week-long attempt to understand things better & how the OS might be handling some of the asynchrony/threading behind the scenes. If you look under the syntactical sugar, there is a lot (read State machines) happening to make your head spin .. if you don’t believe me, watch some of the Channel 9 videos with the Async team.

We had two mechanisms/patterns for doing asynchronous programming before:

  • Asynchronous Programming Model(APM): This is the traditional Asynchronous programming pattern where expensive operations are invoked through BeginXXX/EndXXX pairs .. essentially we fire off an operation after assigning an Async callback handler, which was provided the result handle to receive context when execution completed. More details here.
  • Event-based Asynchronous Programming(EAP): This is the more sophisticated brother of APM, where the callbacks were wired up through event-handling. Remember the times when you did DoSomethingComplete += ExecutionEndFunction()... Yep, that is EAP pattern. You can start learning more here.

While these worked, they were not pretty. More so, in the Silverlight/WPF/Windows Phone world, these asynchronous operations were almost always fired off from a separate non-UI thread. So, your completion-event-handler could not get access to UI elements, resulting in cross-thread exceptions or you scratching head for hours :) So, we ended up doing the gobblygook Dispatcher.BeginInvoke(()=>..) to marshall results back to the UI thread. Yuk! And god forbid if you had to do looping/nested callbacks .. all bets were off with your error handling & logical program flow!

So, C# 5.0 introduces two keywords to make life easier: Async & Await. The Async goes on to describe a method as Async; this does not mean that the method would run asynchronously .. just an indicator for the compiler to expect some long-running procedures within the method. And then comes the Await to indicate that processing should halt, since we are doing something expensive like I/O or fetching data. So essentially, this is a Pause & Play mechanism; the compiler does the wire-ups & returns control to the calling method immediately without blocking. This is rather convenient, since your code to process the results of the expensive operation could be right after the Await statement; but all that would be kept on hold until execution completes.

A lot of this is working because of the magic of Task or Task<T> .. essentially returning a “Promise” to the compiler that some time in future, results of the expensive operation will be returned to the calling statement. As Bill Wagner (@billwagner) puts it, you’re being given an empty envelope without blocking, and you’re asked not to open it until you’re told to do so. All the goodness of Task Parallel Library(TPL) is now in-built.

Here’s an interesting few lines from MSDN on what happens behind the scenes with an awaitable Task:

Precisely how the result of type T is going to be produced in the future is an implementation detail of a particular task; the work might be farmed out to another machine entirely, to another process on this machine, to another thread, or perhaps the work is simply to read a previously cached result that can be accessed cheaply from the current thread. TPL tasks are typically farmed out to worker threads from a thread pool in the current process, but that implementation detail is not fundamental to the Task type; rather, a Task can represent any high-latency operation that produces a T.

So in essence, as you do async-await, things may or may not happen on a background thread, based on what the operation is. If computation, then the OS is possibly doing it on another thread from the threadpool. But if it is simply waiting for an HTTPResponse while staring down a pipe, may be we don’t need another thread .. the OS can handle it at the lowest level through I/O Completion Ports (details here) & marshall the response back to the .NET thread as appropriate. The point is .. you as a developer do not care & can write asynchronous code that flows very similar to synchronous code. Let’s see some code, shall we?

                      
private async LoadSomeData()
{ 
  var client = new HttpClient();
  Uri someDataURI = new Uri("some http endpoint");
  try
  {
     HttpResponseMessage response = await client.GetAsync(someDataURI);

     // Processed like a Callback.
     string xmlResponse = response.Content.ReadAsString();

     // Parse & bind to UI...
  }
}

The above is the simplest form of the new asynchronous code. We define a simple method which returns void, but is marked as an Async method. This tells the compiler that the method essentially needs to be re-written at compile time, where the first Await does it’s wiring up & immediately returns control to the calling method. The above example shows us fetching some data over HTTP using the new GetAsync type asynchronous operations & the Await keyword. This is all great & eventually when CTP ends, most of the network stack APIs will have “async” type operations supported. But until then, we might have to do a few tricks.

Consider this .. you have a WCF Service which exposes a method called Foo. Now, there are a few things you could server-side to make Foo invocation asynchronous (get hints from this post); but let’s say we didn’t since we may not have known to do so. Now, when we add a Service Reference to our WCF Service in a .NET project, guess what we shall get for supported methods? Yup — Foo(), BeginFoo() & EndFoo().

So, you see that we have a little problem. Without your service taking explicit action to return Tasks or asynchronous network API support, you don’t have the “FooAsync()” method! So, is this going to spoil all that we talked about? Let’s look at some code:

                      
private async void LoadSomeData()
{ 
  var results = await Task<IEnumerable<CustomT>>.Factory.StartNew(() => FetchData()); 

  // This fires only after we have a response back. 
  this.ParseAndBindData(results);
}

private IEnumerable<CustomT> FetchData()
{
   var client = new SomeCustomContext(new Uri("some http endpoint"));
   return client.CustomT.Execute();
}

Ok, so let’s step back & see what happened in the above code. With a custom service-bound DataContext, we see a collection of type T & an Execute() synchronous method to fetch some data. Now, we do have an Async method & we are using Await to fetch the data. So, as per convention, our UI thread should be non-blocking; Await immediately returns handle back to calling method. However, inside the FetchData method that we fired to actually fetch the data, we used a synchronous method .. so, is this going to block? I have tried confirming from various sources that it actually will *NOT*. Doing the TaskFactory.StartNew is an explicit way to use offload the work onto a different thread; so it does not matter that our actual data fetch is synchronous. The Await keyword works as expected & the UI thread is not blocked, allowing your application to be responsive while a background thread fetches the data & marshalls the results back into the UI thread. So, all parsing & binding of data should not happen until the data is available & the main UI thread remains responsive.

Now, I know what you are thinking .. this is borderline Sad Panda, right? Wouldn’t it be nice to actually fetch the data through asynchronous means, and not just through a background thread? Keep in mind though that you do not have explicit async methods off of your WCF/OData Service .. however, there is a pattern to wrap your APM BeginXXX/EndXXX methods into an async method call. I have heard about this pattern from quite a few folks; but could not find decent examples myself. So, pointers in that regard are very welcome .. in the meantime, here’s my attempt:

                      
 private async void LoadCustomData()
 {
   var client = new CustomContext(new Uri("some HTTP endpoint"));
   var results = await Task<IEnumerable<CustomT>>.Factory.FromAsync(client.CustomT.BeginExecute(AnotherEndContinuation, client), ContinuationDelegate);

   // This fires only after we have a response back. 
   this.ParseAndBindData(results);
 }

 Func<IAsyncResult, IEnumerable<CustomT>> ContinuationDelegate = EndContinuation;
 private static IEnumerable<CustomT> EndContinuation(IAsyncResult result)
 {
    CustomContext client = (CustomContext)result.AsyncState; 
    return client.CustomT.EndExecute(result);
 }

 private static void AnotherEndContinuation(IAsyncResult result)
 {
    // Do nothing here.
 }

As you can see, we are using the TaskFactory.FromAsync to return an Awaitable collection of CustomT and wrapping the Begin/End calls into one. Yes yes, we should probably write an Extension method doing this wrap up to expose an ExecuteAsync method .. this will make our async-await implementation very clean. But, I have a more basic problem with the API .. may be it is not quite ready yet or I am missing something. Let’s take a closer look at the TaskFactory.FromAsync() API here. You’ll notice that the simplest one I’m using takes two arguments & has this form — FromAsync(IAsyncResult, Func<IAsyncResult, TResult>). The IAsyncResult is provided by calling our BeginXXX method & the Continuation delegate through wiring up a Func<> pattern.

This is where lies my big problem. I need to be returning an Task<IEnumerable<CustomT>> from my delegate to make the FromAsync statement compile. However, the BeginXXX only allows for wiring up an AsyncCallBack method which returns Void. So, I end up writing two End Continuation delegates to make the code compile. Both get hit if debugging, but I only need the one which returns the IEnumarable. So, while this works, it is clunky. Tell me what am I missing? Hoping to get feedback from the likes of Mads Torgersen, Stephen Toub or Bill Wagner to understand these async conversions better.

What’s in it for us? Well, if you doing Windows Phone/Silverlight/Windows 8 Metro development, a non-blocking UI is not a luxury, but a necessity when doing expensive operations. These new keywords of async-await could become your best friends in doing asynchronous programming & yet keep your code very simple/readable in a continuous flow.

That’s all I had. Please please provide feedback if you are up late trying these tricks ..

Adios!