Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

Simplifying Async Networking with Tasks in Silverlight 5

Pete Brown - 04 September 2011

This is a modified excerpt from chapter 17 "Networking Basics" in Silverlight 5 in Action. You can thank James Manning (no relation to the publisher) for this being in the book. Persistence pays off :)

Shameless pimping: If you're looking for a one-stop shop for learning Silverlight 5, consider my book Silverlight 5 in Action, to be released in print near the end of this year. It's currently in MEAP, with purchasers able to download chapters as I make them available. Please, support my family, my children and buy my book … ok, I'll be honest: Please, support my electronics, robotics, CNC, woodworking, synthesis and other habits :)

For background, here's The HttpWebRequest/HttpWebResponse listing 17.2 referred to from the Tasks portion of the chapter

public class RequestState
{
public WebRequest Request { get; set; }
}

public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
InitiateWebRequest();
}

private void InitiateWebRequest()
{
string uri = "http://localhost:47498/helloWorld.xml";

var request = HttpWebRequest.Create(uri);

var state = new RequestState() { Request = request };

var asyncResult =
(IAsyncResult)request.BeginGetResponse(
new AsyncCallback(ResponseCallback), state);
}

private static void ResponseCallback(IAsyncResult asynchronousResult)
{
var state = (RequestState)asynchronousResult.AsyncState;
var request = state.Request;

var response =
(HttpWebResponse)request.EndGetResponse(asynchronousResult);

var stream = response.GetResponseStream();
var reader = new StreamReader(stream);

string xmlFileText = reader.ReadToEnd();

Debug.WriteLine("Status Code: " +
response.StatusCode);
Debug.WriteLine("Status Description: " +
response.StatusDescription);
Debug.WriteLine(xmlFileText);
}
}

17.1.1 Simplifying with Tasks

The Task Parallel Library (TPL) is a section of the full .NET 4 framework which includes the ability to manage asynchronous and parallel operations. The subset of what is included in Silverlight 5 specifically targets the asynchronous part of the TPL, leaving out the parallel bits for now.

The Task class exists in the System.Threading.Tasks namespace, and is included as part of the runtime (no additional references required. It's a core Silverlight feature. Like Rx, Tasks were not created specifically to deal with networking, but they are very useful in this space in Silverlight, especially when working with HttpWebRequest and HttpWebResponse using the async request/response pattern. The Task class is where all the goodness lies.

Taking the same project we created in listing 17.1 and 17.2 on the request/response pattern, we can simplify the code using Tasks as shown in listing 17.10

Listing 17.10 Using Tasks to handle asynchronous operations

private void InitiateWebRequest()
{
string uri = "http://localhost:47498/helloWorld.xml";

var request = HttpWebRequest.Create(uri);

var webTask = Task.Factory.FromAsync<WebResponse>(
request.BeginGetResponse, request.EndGetResponse, null)
.ContinueWith(
task =>
{
var response = (HttpWebResponse)task.Result;
var stream = response.GetResponseStream();
var reader = new StreamReader(stream);
string xmlFileText = reader.ReadToEnd();

Debug.WriteLine("Method: " + response.Method);
Debug.WriteLine("Status Code: " + response.StatusCode);
Debug.WriteLine("Status Description: " + response.StatusDescription);
Debug.WriteLine(xmlFileText);
});
}

Go back and look at listing 17.2 and compare the code to what we have here. This is a significant reduction in code and number of functions when compared to the original listing. The function that makes that possible is the built-in Task.Factory.FromAsync method. That function has knowledge of the async request/response pattern, which just happens to be what is used by WebRequest and WebResponse when making your networking calls.

In this listing, I start by creating the request just as we did before. After that, however, I take a turn and instead of calling any other request functions ourselves, I create a task. The task, because it knows about the async pattern, needs only be provided with the begin and end functions and, optionally, a state object. Because we don't need to access the request ourselves, we're able to get rid of the state object we had in the previous version of this code.

When the task completes, the code in the .ContinueWith statement is executed. This is what you can use to chain networking calls, similar to what we did with Reactive Extensions, but arguably even cleaner. In this example, I simply get the response stream and display the XML file results to the debug window.

Just as was the case with Rx, this only scratches the surface of what you can do with Tasks, and with the TPL in general.

Now, all this may seem like a little much for a "basics" chapter, but it's important for you to understand that there are ways to manage this whole async thing, that don't involve losing all your hair and your sleep. I won't use Rx or Tasks in the examples in this book as they are layers between you and learning the fundamentals. However, in your real code, you'll almost certainly want to turn to them for non-trivial networking operations.

All of our examples so far have either used networking to a web project in the same solution, or have eschewed networking completely to simply simulate the asynchronous operations. Once you start accessing services on other sites, you'll run into cross-domain restrictions.

(the next section is on cross-domain networking and client access policy settings)

Other great references for this topic:

     
posted by Pete Brown on Sunday, September 4, 2011
filed under:      

11 comments for “Simplifying Async Networking with Tasks in Silverlight 5”

  1. Petesays:
    @David

    Thanks. Yeah, I had to move a bunch of chapters into download-only appendix versions, so there was some renumbering. Turns out publishers prefer not to print 1200 pages of text ;)

    @ra

    There's an async targeting pack for Silverlight 5 if you're using Visual Studio 2012

    @Unni

    Thanks!

    Pete
  2. Tom McKearneysays:
    Yes, this book pretty much rocks for Silverlight Developers... I may be a bit biased, since I'm the tech reviewer, but I actually just hit this page on a google search and it made me chuckle... the TPL stuff in Silverlight is nice :)
  3. Jerrysays:
    Pete, Great article man! I agree this and your book Rocks!

    I have the safari online version of your SL5 in Action and i'm hoping you get paid by them for the great work! I see you have expensive hobbies too! Now i'm going back into the book and read this chapter 17 or 19. One thing is it possible to get a good example of this with proper error handling and can you tell me if using this example leaks memory for SL5? I will also purchase a hardcopy of this book for when i'm on the road or just want a real book! Thanks for all the hard work Pete! Some of us are still in the trenches!
  4. Petesays:
    @Jerry

    I've never seen Safari on my royalty sheet. If I get anything through those, I suspect it's much lower than any other channels. Unfortunately, SL5iA lost a ton of money anyway as folks generally moved away from SL as I was getting the book out in stores :P

    Async: I'm not aware of memory leaks. If you have a small repro, please get it to me so I can get it to the product team.

    Pete
  5. Jerrysays:
    Hey Pete, you should look into the safari royalities. I know a lot of work went into the book and i really appreciate the work you did!! I'm going to go out and get the hardcopy this weekend (order online). I'll try to do some small projects to see if i can nail down my memory problems. I'm not sure there is an issue with the async but I have read online a few people have said anonymous methods are leaky with SL. I wrote this really nice web application using SL5 and now once you log in (child window) and close it the memory starts to climb. 30 minutes or more the app just locks up.I'll get to the bottom of it and i'll post another message / project if i determine it's something related to the way i'm calling the web api services. Thanks for the response Pete!

Comment on this Post

Remember me