如何将 .net 4.5 异步/等待示例转换回 4.0

本文关键字:转换 等待 异步 net | 更新日期: 2023-09-27 18:36:57

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

如何将 .net 4.5 异步/等待示例转换回 4.0

注意:这仅适用于异步/等待部分。

最简单的方法是使用异步 CTP。它有一个上线许可证,这意味着你可以在生产代码中使用它。如果异步 CTP 不提供异步等效项,则必须进行一些修改。

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

我已经在生产中使用异步CTP一年多了,没有问题。我肯定会推荐这个。升级到 .NET 4.5 相当容易,基本上只需要更改一些类名(TaskEx 到 Task)和一些签名更改。

如果可以使用 Visual Studio 2012 RC,则还可以使用异步目标包,这将允许您在 .NET 4 中使用异步代码,与使用异步 CTP 相比,更改更少。

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

ParallelExtensionsExtras 包括 WebClient 的异步任务,如果您决定从 HttpClient 切换到 WebClient,这可能会很有用。

作为一个探索如何在 .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
安装: 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 时,您将收到错误(尽管这些关键字仍显示为关键字),例如:

找不到"异步"修饰符所需的所有类型。你是 以错误的框架版本为目标,或缺少对 集会?

因此:

=====

== 步骤#3)视觉工作室的异步目标包==

=====

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

PM> Install-Package Microsoft.CompilerServices.AsyncTargetingPack

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

Installs 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 版本,填充了许多新的任务功能。TaskEx仅适用于4.0版本...所以.NET 4.5:"Task.Run"在4.0中:"TaskEx.Run",这个库的许多其他东西都是这样的)

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

警告 没有错误检查!

好吧,我觉得我今天学到了一些东西,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;
        }
    }
}

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