【问题标题】:How do I call a method that returns a Task<T> From an ASP.Net MVC4 Controller Method?如何调用从 ASP.Net MVC4 控制器方法返回 Task<T> 的方法?
【发布时间】:2013-12-26 04:15:21
【问题描述】:

TL;DR: 我想知道如何从 ASP.Net MVC4 控制器调用返回 Task&lt;T&gt; 的方法获取返回值ActionResult 方法。代码如下:sn-ps。

问题详情:
我在 github 上使用Instasharp Library

这是返回Task&lt;UserResponse&gt;Search 方法。这是在 Instasharp 库中定义的。

/// <summary>
/// Search for a user by name.
/// <para>
/// <c>Requires Authentication: False</c>
/// </para>
/// </summary>
/// <param name="searchTem">A query string.</param>
/// <param name="count">Number of users to return.</param>
/// <returns>UsersResponse</returns>
public Task<UsersResponse> Search(string searchTerm, int? count = null) {
    var request = base.Request("search");

    request.AddParameter("q", searchTerm);
    request.AddParameter("count", count);

    return base.Client.ExecuteAsync<UsersResponse>(request);
}

这是同一库项目源代码中的单元测试,它有效。如果我在Assert 行设置断点并检查result,它包含List&lt;UserResponse&gt; 的实例以及来自Instagram API 的数据。

    [TestMethod, TestCategory("Users.Search")]
    public async Task Search()
    {
        var result = await users.Search("shiva");
        Assert.IsTrue(result.Data.Count > 0);
    }

在我的 ASP.Net MVC4 应用程序的 HomeController 中,在 Index 方法中,该方法将查询 instagram API 并返回强类型 List&lt;Instasharp.Models.User&gt;(包含在 UserResponse 对象的 Data 属性中) 到对应的View,代码如下。 (注意:这是根据 Github 页面上的文档,应该可以工作。)。

   public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var userList = new List<InstaSharp.Models.User>();
            var mediaList = new List<InstaSharp.Models.Media>();
            var followingList = new List<InstaSharp.Models.User>();
            try
            {
                 var config = new InstaSharp.InstagramConfig(
                     clientId:"MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM",
                     clientSecret:"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");

                 InstaSharp.Endpoints.Users users = new InstaSharp.Endpoints.Users(config);
                  var result = users.Search("shiva");
                  userList = result.Result.Data;
            }
            catch (Exception ex)
            {
                ViewBag.Message = ex.Message + "\n\n" + ex.StackTrace.ToString();
            }

            return View(userList);
        }
    }

问题:
我的代码挂起(即localhost:portnumber 正在等待。)。使用 Instagram API 进行身份验证没有问题。线

var result = users.Search("shiva");

显示结果是Task。我不知道如何调用它并从users.Search("shiva") 方法的返回值中获取Data

我的尝试:
我尝试在users.Search("shiva") 调用前添加await。然后编译器要求我制作 ActionResult Index()async 并在其周围包裹 Task&lt;..&gt;。当我也这样做时,代码挂起。 我还尝试在 MSDN at this tutorial 上查看,但这也无济于事。 我在这上面花了好几个小时,希望 SO 上的人能帮助我。

[注意:这不是生产代码。我只是想让 Instasharp 库在 ASP.Net MVC4 控制器中工作并在视图中显示数据。所以请不要专注于编码实践等。另外,我已经伪造了ClientIdClientSecret 的问题。我认为您不需要它来回答这个问题。]

【问题讨论】:

  • 旁注:有很多类似的问题解释“在 ASP.Net 中使用 Wait/Result 时出现死锁”...
  • 谢谢@AlexeiLevenkov 我只是不知道如何进行调用。

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


【解决方案1】:

要在 MVC4+ 中正确调用 async 方法,您应该通过返回 Task&lt;ActionResult&gt; 并使用 await 等待 async 方法完成来使您的操作异步。

在下面的 MSDN 文章 Using Asynchronous Methods in ASP.NET MVC 4(以及许多其他文章)中有详细介绍。以下文章示例:

public async Task<ActionResult> GizmosAsync()
{
    var gizmoService = new GizmoService();
    var result = await gizmoService.GetGizmosAsync();
    return View("Gizmos", result);
}

请注意,在 ASP.Net 中使用 WaitResult 会导致死锁(如您所见)。有很多问题/文章讨论它 - 即await vs Task.Wait - Deadlock?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-23
    • 2022-06-21
    • 2014-08-14
    • 2016-10-05
    • 1970-01-01
    • 2015-01-01
    相关资源
    最近更新 更多