【问题标题】:Async method does not return asp.net mvc 4异步方法不返回 asp.net mvc 4
【发布时间】:2013-04-16 10:52:36
【问题描述】:

我实现的异步方法有问题。该方法基本上向资源发出 HttpRequest 并在请求成功时反序列化字符串。我为该方法编写了一个测试,它有效。但是当我从控制器调用它时,该方法永远不会返回?

    public async Task<IEnumerable<T>> Get()
    {
        try
        {
            var resourceSegmentUri = new Uri(_uri, UriKind.Relative);

            var response = await _client.GetAsync(resourceSegmentUri);

            if (response.IsSuccessStatusCode)
            {
                var submission = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<IEnumerable<T>>(submission);
            }

            if (response.Content != null)
            {
                var message = response.Content.ReadAsStringAsync();
                throw new WebException(message.Result, (WebExceptionStatus)response.StatusCode);
            }

        }
        catch (WebException e)
        {
            Logger.Error("GET Request failed with status: {0}", e.Status);
            throw;
        }

        throw new Exception();
    }

永不返回的代码:

public ActionResult Index()
{
   var api = new Api();
   var test = api.Get().Result; //Never returns
   return View();
}

测试有效:

[Test]
public void GetShouldReturnIfSuccessfulRequest()
{
    var api = new Api();
    var submission = api.Get();

    Console.WriteLine(JsonConvert.SerializeObject(submission));
    Assert.NotNull(submission);
}

有人知道这个问题吗?

【问题讨论】:

  • 我不确定我是否理解您的问题。您的 Index() 方法中没有 return ...; 语句,因此它无法返回任何内容。
  • 很抱歉错过了return语句,但这真的无关紧要。
  • 更改您的测试,以便获得异步方法的结果,否则您不会测试您的意图。 api.Get() 应该是 api.Get().Result

标签: c# asp.net asp.net-mvc asynchronous


【解决方案1】:

您遇到了死锁,因为您在控制器操作中调用了.Result

如果您使用async/await,那么您也必须使用异步操作。

所以这样的事情应该可以解决它:

public async Task<ActionResult> Index()
{
  var api = new Api();
  var test = await api.Get(); // Should return
}

这里有一篇关于此的综合文章:Using Asynchronous Methods in ASP.NET MVC 4

【讨论】:

  • 不起作用。我试过了。基本上在我的实际解决方案中,我将 Get() 方法包装在一个将模型返回给控制器的服务方法中。
  • @BjBlazkowicz 那么最好的选择就是将服务方法也设为async。如果您开始使用async/await,则必须在调用堆栈中一直使用它。
  • 我已将服务方法设为异步,但仍然无法正常工作。问题是我在 NUnit 中为它编写了一个测试,它工作正常。但是从控制器调用该方法时永远不会返回。
  • @BjBlazkowicz 刚刚看到您的编辑 - 在您的测试中,submission 将是 Task 而不是结果,因此它并没有真正测试您的方法。
  • +1。 @BjBlazkowicz:我在on my blogrecent MSDN article 中解释了僵局的原因。
猜你喜欢
  • 2012-07-05
  • 2012-04-16
  • 2014-10-22
  • 1970-01-01
  • 2012-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-16
相关资源
最近更新 更多