How do I convert .net 4.5 Async/Await example back to 4.0

14,995

Solution 1

NOTE: This is only for the Async/Await part.

The easiest way would be to use the Async CTP. It has a Go live license which means you can use it in production code. You will have to make some modifications in cases where the Async CTP doesn't provide async equivalents.

You can use Async CTP on Azure as the only thing required is an extra DLL. There is a similar SO question here Async CTP and Windows Azure Support

I've been using Async CTP in production for over a year without problems. I'd definitely recommend this. Upgrading to .NET 4.5 is rather easy, essentially requiring only some class name changes (TaskEx to Task) and a few signature changes.

If you can use Visual Studio 2012 RC you can also use the Async Targeting pack which will allow you to use your async code in .NET 4 with fewer changes than if you use the Async CTP.

Finally, the brute-force solution is to use the TaskIterator from the ParallelExtensionsExtras samples to emulate what async/await does. You will have to convert all asynchronous invocations to tasks, or methods that return a task, and then iterate over the list of those tasks. It's a lot more code but it's the only solution if you don't want to use CTP code, even if it has a Go Live license.

The ParallelExtensionsExtras include asynchronous tasks for the WebClient which may be useful if you decide to switch from HttpClient to WebClient.

Solution 2

As someone exploring how to get all of this working in .NET 4.0 as well, I haven't found the given answers on this thread and others complete enough to immediately get up and running. So the following is a more comprehensive answer of what to simply do:

======= STEP #1) INSTALL Microsoft ASP.NET Web API Client Libraries (RC) 4.0.20505.0 =======

http://nuget.org/packages/Microsoft.AspNet.WebApi.Client

PM> Install-Package Microsoft.AspNet.WebApi.Client

INSTALLS: System.Net.Http.dll, System.Net.Http.Formatting.dll, System.Net.Http.WebRequest.dll, Newtonsoft.Json.dll

======= STEP #2) Microsoft .NET Framework 4 HTTP Client Libraries 2.0.20505.0 =======

http://nuget.org/packages/Microsoft.Net.Http.

PM> Install-Package Microsoft.Net.Http.

If you followed step #1 already, NuGet should have actually already grabbed this dependency: System.Net.Http.dll. System.Net.Http. is what provides HttpClient, HttpRequestMessage and HttpResponseMessage.

At this point, you will be getting errors when using async/await (though these keywords still show up as keywords) saying things like:

Cannot find all types required by the 'async' modifier. Are you targeting the wrong framework version, or missing a reference to an assembly?

Thus:

======= STEP #3) Async Targeting Pack for Visual Studio =======

http://www.microsoft.com/en-us/download/details.aspx?id=29576

PM> Install-Package Microsoft.CompilerServices.AsyncTargetingPack

('...Visual Studio 11' name needs updated on NuGet, both are version 1.0.0)

Installs 1 dll: Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll

"The "Async Targeting Pack for Visual Studio 2012" enables projects targeting .NET Framework 4.0 or Silverlight 5 to use the Async language feature in C# 5 ... " http://www.microsoft.com/en-us/download/details.aspx?id=29576

Among other things, adds TaskEx (a .NET 4.0 version that fills in many new Task features. TaskEx is only for the 4.0 version... so .NET 4.5: "Task.Run" is in 4.0: "TaskEx.Run", many other things are like this with this library)

Suddenly, await and async and the whole works starts working like a charm! If you reflect in, one of the most important things about this is the class (declared without a namespace): AsyncCompatLibExtensions. A static class containing extension methods onto especially: 1) Stream. E.g. ReadAsync. So now stream.ReadAsync suddenly appears! (it actually cleanly wraps stream's BeginRead/BeginWrite, if you want to know), 2) WebClient. E.g. webClient.DownloadStringTaskAsync, and more.

Solution 3

WARNING There is no error checking!

Well I feel like I learned something today, have a read of this article http://blogs.msdn.com/b/pfxteam/archive/2010/11/21/10094564.aspx to learn a better way to handle this :)

using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Mvc;
using Newtonsoft.Json;
namespace DribbbleR.Web.Controllers
{
    public class HomeController : Controller
    {
        private static dynamic shots;
        private HttpClient client = new HttpClient();
        private string url = "http://api.dribbble.com/shots/everyone?per_page=30";

        public Task<dynamic> Index()
        {    if (shots == null)
             shots = Task.Factory.StartNew
                   (() => return DownloadContent();).Unwrap();    
             return shots;
        }
        public Task<dynamic> DownloadContent()
        {    var responseTask = client.GetAsync(url);
             var readTask = responseTask.ContinueWith
                 (t =>
                     {   t.Result.EnsureSuccessStatusCode();
                         return t.Result.Content.ReadAsStringAsync();
                      }
                  ).Unwrap();
            var deserializeTask = readTask.ContinueWith
                  (t => return JsonConvert.DeserializeObjectAsync<dynamic>(t.Result);)
            .Unwrap();
            var viewTask = deserializeTask.ContinueWith
                  (t =>  return this.View(t.Result););
            return viewTask;
        }
    }
}

Solution 4

You can use Async Targeting Pack for Visual Studio 2012 http://www.microsoft.com/en-us/download/details.aspx?id=29576

Share:
14,995

Related videos on Youtube

superlogical
Author by

superlogical

Developer from New Zealand! C# .Net/Mono MonoTouch/Mono for Android/Xamarin.Mac Objective-C/iOS Git/Mecurial CSS/SASS MongoDB/Redis/SQL Server/Search/RavenDB/CouchDB/TouchDB Javascript/Node/jQuery/Backbone/CoffeeScript/Angularjs Ruby/Ruby on Rails

Updated on September 26, 2022

Comments

  • superlogical
    superlogical over 1 year

    What would the equivalent asp.net mvc 4.0 code look like?

    using System.Net;
    using System.Net.Http;
    using System.Web.Mvc;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    namespace Web.Controllers
    {
        public class HomeController : Controller
        {
            private HttpClient httpClient = new HttpClient();
            private static dynamic shots;
    
            public async Task<ActionResult> Index()
            {
                if (shots == null)
                {
                    try
                    {
                        var responseMessage = 
                           await httpClient.GetAsync
                                ("http://api.dribbble.com/shots/everyone?per_page=30");
                        responseMessage.EnsureSuccessStatusCode();
    
                        var value = await responseMessage.Content.ReadAsStringAsync();
                        shots = await JsonConvert.DeserializeObjectAsync<dynamic>(value);
                    }
                    catch (WebException)
                    {
                    }
                }
                return View(shots);
            }
        }
    }
    
    • Panagiotis Kanavos
      Panagiotis Kanavos almost 12 years
      The Task Parallel Library is a feature of .NET 4 that works very well. There is absolutely no need to use a much heavier and more cumbersome backgroundworker
  • superlogical
    superlogical almost 12 years
    The HttpClient is on NuGet and you can use it from .Net 4.0. The reason why I am targeting .Net 4.0 is because AppHarbor and Azure are still using .Net 4.0 and won't be upgrading until Windows 8 and Server 2012 are released. Thanks for the link to that TaskIterator page I will check it out :)
  • Panagiotis Kanavos
    Panagiotis Kanavos almost 12 years
    You can use Async CTP even in Azure as you only have to deploy an extra DLL.
  • Panagiotis Kanavos
    Panagiotis Kanavos almost 12 years
    PS ... I've lost countless hours dealing with WebClient and its gratuitous exceptions. Wish I knew about HttpClient on Nuget 6 months ago ...
  • superlogical
    superlogical almost 12 years
    Oh okay, haha will have to test it out. Yeah there is lots of out of band releases happening with the RC bits being released by MS via NuGet which is pretty cool.
  • Gennady Vanin Геннадий Ванин
    Gennady Vanin Геннадий Ванин almost 11 years
    But HttpClient is not available in in .NET 4.0 even after installling Async CTP or bringing AsyncCtpLibrary.dll from it!
  • Panagiotis Kanavos
    Panagiotis Kanavos almost 11 years
    HttpClient is not in the Async CTP, it is in its own package
  • Gennady Vanin Геннадий Ванин
    Gennady Vanin Геннадий Ванин almost 11 years
    @ PanagiotisKanavos, Is it in its own package only in case of ".NET4.0/VS2010 + Async CTP"? There are no docs for it. So, I passed a dozen How-to and Walkthroghs on async/await programming for VS2012 (.NET 4.5). Most uses HttpClient but never mentions a step of installing a package for getting System.Net.Http.dll
  • Nicholas Petersen
    Nicholas Petersen almost 11 years
    I can't believe someone just gave me a downvote for patiently contributing this information to the community. If you are a true man or woman, how about posting a comment with it. You are probably the same person who voted down er-v above, which is senseless. And btw, note the date, 4.5 was not out yet, so this answer may likely now be superseded.
  • Nicholas Petersen
    Nicholas Petersen almost 11 years
    Ridiculous that someone voted this down as well as my answer below. I voted it up to equal it back out.
  • Panagiotis Kanavos
    Panagiotis Kanavos almost 11 years
    Did you search for HttpClient on NuGet? There are over 30 results for HttpClient, for the library itself and its extensions. You won't find references to packages in MSDN, especially not for CTP or pre-release packages