From 52fa277757472695d5e51c0bf2ba545e0188fcc5 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Tue, 17 Apr 2012 18:10:34 +1000 Subject: [PATCH 1/7] initial post --- _posts/2012-04-18-show-and-tell-garfbradaz.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 _posts/2012-04-18-show-and-tell-garfbradaz.md diff --git a/_posts/2012-04-18-show-and-tell-garfbradaz.md b/_posts/2012-04-18-show-and-tell-garfbradaz.md new file mode 100644 index 0000000..f0c4fcc --- /dev/null +++ b/_posts/2012-04-18-show-and-tell-garfbradaz.md @@ -0,0 +1,15 @@ +--- +layout: post +permalink: /show-and-tell/2/mvc-photo.html +date: 2012-04-18 23:00 +title: "Show and Tell #2 - Learning MVC and building MvcPhoto" +author: "@shiftkey" +comments: true +--- + +## Introduction + +[introduction post](http://garfbradazweb.wordpress.com/2012/04/16/code52-show-tell-my-open-source-application/) + + +## About the Author From 5e5f4ec78bd53a3a6d0baf36015ce21e973a246b Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Tue, 17 Apr 2012 20:01:28 +1000 Subject: [PATCH 2/7] fleshed out post --- _posts/2012-04-18-show-and-tell-garfbradaz.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/_posts/2012-04-18-show-and-tell-garfbradaz.md b/_posts/2012-04-18-show-and-tell-garfbradaz.md index f0c4fcc..9f6069a 100644 --- a/_posts/2012-04-18-show-and-tell-garfbradaz.md +++ b/_posts/2012-04-18-show-and-tell-garfbradaz.md @@ -1,15 +1,21 @@ --- layout: post -permalink: /show-and-tell/2/mvc-photo.html +permalink: /show-and-tell/2/mvc-image.html date: 2012-04-18 23:00 -title: "Show and Tell #2 - Learning MVC and building MvcPhoto" +title: "Show and Tell #2 - Learning by building MvcImage" author: "@shiftkey" comments: true --- + ## Introduction -[introduction post](http://garfbradazweb.wordpress.com/2012/04/16/code52-show-tell-my-open-source-application/) +This post is from Gareth, who found the Code52 chatroom by chance. When we announced the "Show and Tell" week, he put together a post about what he does for a living and what [he's been learning in his spare time](http://garfbradazweb.wordpress.com/2012/04/16/code52-show-tell-my-open-source-application/). + +I share the same view as Gareth in that I **learn best by building something useful** - and Gareth's put together his own OSS project to demonstrate his learning. +The project code is at [mvcimage.codeplex.com](http://mvcimage.codeplex.com/), and I hope to see more stuff from him in the future. ## About the Author + +Gareth is a 4GL applications developer for OpenVMS systems by day and learns various other technologies (including C#, C++, XNA and ASP.NET) by night. You can find his blog at [garfbradazweb.wordpress.com/](http://garfbradazweb.wordpress.com/) and he isn't on Twitter (but probably should be). From 751a85c3866daa830ee89e1024557575be3eda85 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Tue, 17 Apr 2012 20:17:06 +1000 Subject: [PATCH 3/7] minor edits --- _posts/2012-04-18-show-and-tell-garfbradaz.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/_posts/2012-04-18-show-and-tell-garfbradaz.md b/_posts/2012-04-18-show-and-tell-garfbradaz.md index 9f6069a..d5ad1a7 100644 --- a/_posts/2012-04-18-show-and-tell-garfbradaz.md +++ b/_posts/2012-04-18-show-and-tell-garfbradaz.md @@ -10,12 +10,12 @@ comments: true ## Introduction -This post is from Gareth, who found the Code52 chatroom by chance. When we announced the "Show and Tell" week, he put together a post about what he does for a living and what [he's been learning in his spare time](http://garfbradazweb.wordpress.com/2012/04/16/code52-show-tell-my-open-source-application/). +This post is from Gareth Bradley, who found the Code52 chatroom by accident while he was checking out [JabbR](http://jabbr.net/). When we announced the "Show and Tell" week, he wrote a post about what he does for a living and what [he's been learning in his spare time](http://garfbradazweb.wordpress.com/2012/04/16/code52-show-tell-my-open-source-application/). -I share the same view as Gareth in that I **learn best by building something useful** - and Gareth's put together his own OSS project to demonstrate his learning. +I share the same view as Gareth in that I **learn best by building something useful** - and Gareth's put together his own OSS project as a way to demonstrate what he's learned. -The project code is at [mvcimage.codeplex.com](http://mvcimage.codeplex.com/), and I hope to see more stuff from him in the future. +The project code is at [mvcimage.codeplex.com](http://mvcimage.codeplex.com/), and I hope to see more cool stuff from him in the future. ## About the Author -Gareth is a 4GL applications developer for OpenVMS systems by day and learns various other technologies (including C#, C++, XNA and ASP.NET) by night. You can find his blog at [garfbradazweb.wordpress.com/](http://garfbradazweb.wordpress.com/) and he isn't on Twitter (but probably should be). +Gareth Bradley is a 4GL applications developer on OpenVMS systems by day and learning various other technologies (including C#, C++, XNA and ASP.NET) by night. You can find his blog at [garfbradazweb.wordpress.com/](http://garfbradazweb.wordpress.com/) and he's also on Twitter as [@garfbradaz](http://twitter.com/garfbradaz). From 88eb303072b0b38ed09083053bddbe6d051fc9ed Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Tue, 17 Apr 2012 18:10:56 +1000 Subject: [PATCH 4/7] initial post --- _posts/2012-04-19-show-and-tell-mabster.md | 85 ++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 _posts/2012-04-19-show-and-tell-mabster.md diff --git a/_posts/2012-04-19-show-and-tell-mabster.md b/_posts/2012-04-19-show-and-tell-mabster.md new file mode 100644 index 0000000..0dd60ec --- /dev/null +++ b/_posts/2012-04-19-show-and-tell-mabster.md @@ -0,0 +1,85 @@ +--- +layout: post +permalink: /show-and-tell/3/task-parallel-library.html +date: 2012-04-18 23:00 +title: "Show and Tell #3 - Building Budgie with the Task Parallel Library (TPL)" +author: "@shiftkey" +comments: true +--- + +## Introduction + + + +## The problem with asynchronous code + +When thinking about what [Budgie's](http://matthamilton.net/budgie) surface API was going to look like, I knew one thing: it would be asynchronous only. There would be no methods like `GetHomeTimeline()` that blocked and waited for Twitter to respond. + +There are any number of ways to write asynchronous APIs. The one I've been most comfortable with to date (used in TweetSharp, another Twitter library that heavily informed Budgie) is to ask for a callback as a parameter to your method, and call that when your asynchronous task is done. For example: + + public void DoStuff(string text, Action callback) + { + // step 1: do stuff with text asynchronously + DoStuffResult result = ...; + + // step 2: call the callback with the result + callback(DoStuffResult); + } + +This technique works really well, but with the advent of C# 5 and the new "async" and "await" keywords, a new approach became the obvious choice: using the Task Parallel Library. + +The idea is simply to return a "hot" `Task` (that is, a task that is already running) from your method: + + public Task DoStuff(string text) + { + return Task.Factory.StartNew(t => ..., text); + } + +Note that the method above returns a `Task`, which is a special kind of `Task` that returns a result. If your method doesn't need to return a value (like a void method) you would return a non-generic `Task` object instead. + +The calling code can then decide what to do with that task. They might decide to block and wait for it to finish: + + DoStuffResult result = DoStuff("hello world").Result; + +Or they might use a continuation: + + DoStuff("hello world").ContinueWith(result => { ... }); + +Or, in C# 5, they might use the non-blocking "await" keyword: + + DoStuffResult result = await DoStuff("hello world"); + +Using the Task Parallel Library gives the caller some flexibility in that regard, and the fact that it integrates so seamlessly into the C# 5 syntax made it an obvious choice. + +## Using the TPL with WebRequest + +I decided to use good ol' `System.Net.WebRequest` when making my calls to Twitter, partly because it offered fine-grained control over the request and partly because I was doing "Google Driven Development" and a lot of code samples out there use it. + +`WebRequest` offers an async API in the form of its `BeginRequest` and `EndRequest` methods, and as it turns out, the TPL gives us a really easy way to turn those calls into a `Task`: + + return Task.Factory.FromAsync(request.BeginGetResponse, request.EndGetResponse, null); + +That returns a running Task which is performing the request and will return the response in the `Result` property. + +From there I can use a continuation (since Budgie is written using C# 4 and doesn't make use of the "await" keyword) to take action when the task completes: + + return requestTask.ContinueWith(t => + { + if (t.StatusCode != System.Net.HttpStatusCode.OK) return null; + + Foo result = new Foo(); + + // populate result by deserializing the JSON returned in the response + + return result; + }); + +It's worth noting that `ContinueWith` in this case is returning a `Task`, since I've passed it a `Func` to execute. The fact that I'm "continuing" from a `Task` doesn't mean I have to return that type. + +All in all, it's pretty easy! Easier still had I written this code with C# 5, but I wanted to be able to build this from my home PC which doesn't have .NET 4.5 or the Async CTP installed. + +## Wrapping Up + +Using the TPL to create an asynchronous API is the logical choice in modern .NET development, and I wouldn't have done anything different in Budgie. I'm looking forward to the final release of VS11 and .NET 4.5, at which point I'll refactor the code to make use of the "await" keyword, but for now it's good to know that you can do this in a future-proof way with the current tools. + +## About the Author \ No newline at end of file From ad65fd6708993ef7b403c3380bb4758b489acf81 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Tue, 17 Apr 2012 20:56:35 +1000 Subject: [PATCH 5/7] added intro --- _posts/2012-04-19-show-and-tell-mabster.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/_posts/2012-04-19-show-and-tell-mabster.md b/_posts/2012-04-19-show-and-tell-mabster.md index 0dd60ec..61087c7 100644 --- a/_posts/2012-04-19-show-and-tell-mabster.md +++ b/_posts/2012-04-19-show-and-tell-mabster.md @@ -9,7 +9,11 @@ comments: true ## Introduction +For those of you who aren't familiar with it, [Matt Hamilton](http://twitter.com/mabster) wrote a Twitter API library over a few nights last week as an experiment to better understand the Task Parallel Library. +He's named it Budgie - you can [read up about it](http://matthamilton.net/budgie), browse the [source code](http://bitbucket.org/mabster/budgie), install the [NuGet packages](http://nuget.org/packages/Budgie) or try out his Twitter client [Halfwit](http://madprops.org/halfwit/) which uses it. + +I asked Matt if he was interested in discussing why he decided to use the TPL for his project and what was cool about it. ## The problem with asynchronous code From 66e44534a797ca2aafaaa45ababde5fdbe8235b6 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Thu, 19 Apr 2012 15:37:42 +1000 Subject: [PATCH 6/7] removed last section, updated timestamp --- _posts/2012-04-19-show-and-tell-mabster.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/_posts/2012-04-19-show-and-tell-mabster.md b/_posts/2012-04-19-show-and-tell-mabster.md index 61087c7..80467ba 100644 --- a/_posts/2012-04-19-show-and-tell-mabster.md +++ b/_posts/2012-04-19-show-and-tell-mabster.md @@ -1,7 +1,7 @@ --- layout: post permalink: /show-and-tell/3/task-parallel-library.html -date: 2012-04-18 23:00 +date: 2012-04-19 23:00 title: "Show and Tell #3 - Building Budgie with the Task Parallel Library (TPL)" author: "@shiftkey" comments: true @@ -84,6 +84,4 @@ All in all, it's pretty easy! Easier still had I written this code with C# 5, bu ## Wrapping Up -Using the TPL to create an asynchronous API is the logical choice in modern .NET development, and I wouldn't have done anything different in Budgie. I'm looking forward to the final release of VS11 and .NET 4.5, at which point I'll refactor the code to make use of the "await" keyword, but for now it's good to know that you can do this in a future-proof way with the current tools. - -## About the Author \ No newline at end of file +Using the TPL to create an asynchronous API is the logical choice in modern .NET development, and I wouldn't have done anything different in Budgie. I'm looking forward to the final release of VS11 and .NET 4.5, at which point I'll refactor the code to make use of the "await" keyword, but for now it's good to know that you can do this in a future-proof way with the current tools. \ No newline at end of file From bb569a1be5a42e33977e9e02bab33c3135d43d2f Mon Sep 17 00:00:00 2001 From: Andrew Tobin Date: Thu, 19 Apr 2012 20:17:27 +1000 Subject: [PATCH 7/7] Matt's latest revision --- _posts/2012-04-19-show-and-tell-mabster.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/_posts/2012-04-19-show-and-tell-mabster.md b/_posts/2012-04-19-show-and-tell-mabster.md index 80467ba..a7a88cc 100644 --- a/_posts/2012-04-19-show-and-tell-mabster.md +++ b/_posts/2012-04-19-show-and-tell-mabster.md @@ -65,6 +65,12 @@ I decided to use good ol' `System.Net.WebRequest` when making my calls to Twitte That returns a running Task which is performing the request and will return the response in the `Result` property. +Budgie, however, doesn't use it. Why? Because I wanted all HTTP requests in Budgie to honour a Timeout property, and WebRequest doesn't honour its own Timeout property unless you use the synchronous `GetResponse` method. So my code actually looks like this: + + return Task.Factory.StartNew(() => request.GetResponse()); + +It could be argued that that's actually _more_ readable. :) + From there I can use a continuation (since Budgie is written using C# 4 and doesn't make use of the "await" keyword) to take action when the task completes: return requestTask.ContinueWith(t => @@ -84,4 +90,4 @@ All in all, it's pretty easy! Easier still had I written this code with C# 5, bu ## Wrapping Up -Using the TPL to create an asynchronous API is the logical choice in modern .NET development, and I wouldn't have done anything different in Budgie. I'm looking forward to the final release of VS11 and .NET 4.5, at which point I'll refactor the code to make use of the "await" keyword, but for now it's good to know that you can do this in a future-proof way with the current tools. \ No newline at end of file +Using the TPL to create an asynchronous API is the logical choice in modern .NET development, and I wouldn't have done anything different in Budgie. I'm looking forward to the final release of VS11 and .NET 4.5, at which point I'll refactor the code to make use of the "await" keyword, but for now it's good to know that you can do this in a future-proof way with the current tools.