Debugging Fun with the Async CTP

I was writing a short talk about the Async CTP and as part of that, I wrote this little WPF form which goes off to my local web server to grab an image and display it;

image produces image

when you click on the “Get Image” button that that image is just served up by my local web server and accessed with an HTTP GET.

The code for that looks something like this where OnGetImage is the event handler for the button on the screen;

namespace TaskPlayground
{
  using System.IO;
  using System.Net;
  using System.Windows;
  using System.Windows.Media.Imaging;

  public partial class MainWindow : Window
  {
    static readonly string url = "http://localhost/photo1.jpg";

    public MainWindow()
    {
      InitializeComponent();
    }
    void OnGetImage(object sender, RoutedEventArgs e)
    {
      OnGetImageInternal();
    }
    async void OnGetImageInternal()
    {
      WebClient client = new WebClient();
      byte[] bits = await client.DownloadDataTaskAsync(url);
      FillInPicture(new MemoryStream(bits));
    }
    void FillInPicture(MemoryStream stream)
    {
      stream.Seek(0, SeekOrigin.Begin);
      BitmapImage bitmapImage = new BitmapImage();
      bitmapImage.BeginInit();
      bitmapImage.StreamSource = stream;
      bitmapImage.EndInit();
      this.image1.Source = bitmapImage;
    }
  }
}

but what I thought really highlighted the workings of things was the debugging experience in that if I go add some “breakpoints”;

    void OnGetImage(object sender, RoutedEventArgs e)
    {
      OnGetImageInternal();
      // Breakpoint 1.
      Debugger.Break();
    }
    async void OnGetImageInternal()
    {
      WebClient client = new WebClient();
      byte[] bits = await client.DownloadDataTaskAsync(url);

      // Breakpoint 2.
      Debugger.Break();
      FillInPicture(new MemoryStream(bits));
    }

Then I think most (all?) .NET developers prior to the Async CTP would have been quite happy to borrow money in order to bet that breakpoint 2 would fire before breakpoint 1 and then they’d have retired to a desert island somewhere Smile 

This is the natural order of things. It’s what we intuitively “know”.

Of course, with the Async CTP “everything you know is wrong” because breakpoint 1 fires before breakpoint 2 and, even more surprisingly if you’ve not been following this stuff too closely is that my debugger’s threading window shows me that breakpoint 1 runs on my main thread;

image

and that breakpoint 2 also runs on my main thread;

image

That is ( as I talked about in previous posts and is covered very well elsewhere ) the async CTP work is SynchronizationContext aware and I think that you can see that from the callstacks here although I’m not 100% certain that I’m looking at the right frames as they get a bit “deep” in their interactions with the WPF Dispatcher in this case;

image

"We’re not in Kansas any more” has become my stock phrase of late – this is not your father’s C# ( or VB for that matter ) Winking smile

If you want to get this from “the horse’s mouth” then, of course, you should go watch the talk that Anders gave at BUILD ( make sure that you watch the Smooth Streaming format version at full screen rather than the default version which doesn’t smooth stream and gives you a slightly more shabby experience );