【问题标题】:How do I convert .net 4.5 Async/Await example back to 4.0如何将 .net 4.5 Async/Await 示例转换回 4.0
【发布时间】:2019-12-25 04:49:13
【问题描述】:

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

【问题讨论】:

  • 这真的有效吗?疯狂! .. 得看看这个疯狂的 4.5 东西。如果我想要异步 ui 交互,我使用 ajax/json,如果我想要异步服务器工作而不需要向客户端返回数据,我可能会考虑生成线程或使用 background worker
  • 任务并行库是 .NET 4 的一项功能,效果非常好。绝对没有必要使用更重更笨重的后台工作者

标签: c# asp.net-mvc-4 async-await task-parallel-library


【解决方案1】:

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

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

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

我已经在生产中使用 Async CTP 一年多了,没有出现任何问题。我肯定会推荐这个。升级到 .NET 4.5 相当容易,基本上只需要更改一些类名(TaskEx 到 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,这可能会很有用。

【讨论】:

  • HttpClient 在 NuGet 上,您可以从 .Net 4.0 使用它。我之所以选择 .Net 4.0 是因为 AppHarbor 和 Azure 仍在使用 .Net 4.0,并且在 Windows 8 和 Server 2012 发布之前不会升级。感谢您提供指向该 TaskIterator 页面的链接,我会检查一下 :)
  • 您甚至可以在 Azure 中使用异步 CTP,因为您只需部署一个额外的 DLL。
  • PS ...我已经浪费了无数时间来处理 WebClient 及其无缘无故的异常。希望 6 个月前我知道 Nuget 上的 HttpClient ...
  • 哦,好吧,哈哈必须测试一下。是的,MS 通过 NuGet 发布的 RC 位发生了很多带外发布,这非常酷。
  • HttpClient 不在 Async CTP 中,它在自己的包中
【解决方案2】:

作为探索如何在 .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。系统.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.运行”,这个库很多其他的事情都是这样的)

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

【讨论】:

  • 我不敢相信有人因为我耐心地将这些信息贡献给社区而投了反对票。如果你是一个真正的男人或女人,发表评论怎么样。您可能是同一个人投票否决了上面的 er-v,这是毫无意义的。顺便说一句,请注意日期,4.5 还没有发布,所以这个答案现在可能会被取代。
【解决方案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;
        }
    }
}

【讨论】:

    【解决方案4】:

    您可以使用 Async Targeting Pack for Visual Studio 2012 http://www.microsoft.com/en-us/download/details.aspx?id=29576

    【讨论】:

    • 可笑的是有人投票否决了这个以及我在下面的回答。我投了赞成票以将其取消。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-28
    • 2013-04-29
    • 2012-10-16
    • 1970-01-01
    • 2021-10-19
    • 2021-04-10
    相关资源
    最近更新 更多