如何将 .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);
}
}
}
注意:这仅适用于异步/等待部分。
最简单的方法是使用异步 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