如何将.net 4.5 Async / Await示例转换回4.0

时间:2012-06-12 10:23:53

标签: c# task-parallel-library async-await

等效的asp.net mvc 4.0代码会是什么样的?

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);
        }
    }
}

5 个答案:

答案 0 :(得分:9)

注意:这仅适用于Async / Await部分。

最简单的方法是使用Async CTP。它有一个Go live许可证,这意味着您可以在生产代码中使用它。在Async CTP不提供异步等效的情况下,您必须进行一些修改。

您可以在Azure上使用Async CTP,因为唯一需要的是额外的DLL。这里有一个类似的SO问题Async CTP and Windows Azure Support

我已经在生产中使用Async CTP超过一年没有问题。我肯定会推荐这个。升级到.NET 4.5非常简单,基本上只需要更改一些类名(TaskEx to Task)和一些签名更改。

如果您可以使用Visual Studio 2012 RC,您还可以使用Async Targeting pack,这将允许您使用.NET 4中的异步代码,其更改次数比使用Async CTP时少。

最后,蛮力解决方案是使用ParallelExtensionsExtras示例中的TaskIterator来模拟async / await的作用。您必须将所有异步调用转换为任务或返回任务的方法,然后迭代这些任务的列表。它是更多的代码,但它是唯一的解决方案,如果您不想使用CTP代码,即使它具有Go Live许可证。

ParallelExtensionsExtras包含asynchronous tasks for the WebClient,如果您决定从HttpClient切换到WebClient,这可能很有用。

答案 1 :(得分:5)

有人正在探索如何在.NET 4.0中使用所有这些工作,我没有在这个线程上找到给定的答案,而其他人已经足够完成以立即启动并运行。因此,以下是对简单操作的更全面的回答:

=======步骤#1)安装Microsoft ASP.NET Web API客户端库(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

=======步骤#2)Microsoft .NET Framework 4 HTTP客户端库2.0.20505.0 =======

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

PM> Install-Package Microsoft.Net.Http.

如果你已经按照步骤#1,NuGet应该已经抓住了这个依赖:System.Net.Http.dll。 System.Net.Http。提供HttpClient,HttpRequestMessage和HttpResponseMessage。

此时,使用async / await(尽管这些关键字仍然显示为关键字)时会出现错误,如下所示:

  

找不到'async'修饰符所需的所有类型。你是   定位错误的框架版本,或缺少对该框架的引用   组件?

因此:

=======步骤#3)Visual Studio的异步定位包=======

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

PM> Install-Package Microsoft.CompilerServices.AsyncTargetingPack

('... Visual Studio 11'名称需要在NuGet上更新,两者都是1.0.0版本)

安装1个dll:Microsoft.CompilerServices.AsyncTargetingPack.Net4.dll

“Visual Studio 2012的异步定位包”使针对.NET Framework 4.0或Silverlight 5的项目能够使用C#5中的异步语言功能......“http://www.microsoft.com/en-us/download/details.aspx?id=29576

除此之外,还添加了TaskEx(.NET 4.0版本,它填充了许多新的Task功能.TaskEx仅适用于4.0版本......因此.NET 4.5:“Task.Run”在4.0中:“TaskEx。运行“,这个库中的许多其他东西都是这样的)

突然间,等待和异步,整个作品开始像魅力一样!如果你反思,关于这个的最重要的事情之一是类(声明没有命名空间):AsyncCompatLibExtensions。一个包含扩展方法的静态类,特别是: 1)流。例如。 ReadAsync。所以现在stream.ReadAsync突然出现了! (它实际上干净地包装流的BeginRead / BeginWrite,如果你想知道),2)WebClient。例如。 webClient.DownloadStringTaskAsync等等。

答案 2 :(得分:3)

警告没有错误检查!

我觉得我今天学到了一些东西,请阅读这篇文章http://blogs.msdn.com/b/pfxteam/archive/2010/11/21/10094564.aspx以学习更好的方法来处理这个问题:)

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;
        }
    }
}

答案 3 :(得分:2)

您可以使用Visual Studio 2012的异步定位包http://www.microsoft.com/en-us/download/details.aspx?id=29576

答案 4 :(得分:0)

我不知道你是否找到了这个问题的答案,但我查看了这个链接:

相关问题