【问题标题】:Async controller method not returning异步控制器方法不返回
【发布时间】:2014-09-22 00:44:16
【问题描述】:

当我向它发出请求时,此代码挂起(不返回响应):

public class MyController : ApiController
{
    public async Task<IQueryable<int>> Get()
    {
        return await new Task<IQueryable<int>>(() => new List<int>().AsQueryable());
    }
}

但是这个方法很好用:

public IQueryable<int> Get()
{
    return new List<int>().AsQueryable();
}

我缺少什么基础知识??!

【问题讨论】:

    标签: c# asp.net asp.net-web-api async-await


    【解决方案1】:

    正如另一个答案所述,您的控制器未完成的原因是任务未启动。但是,在 ASP.NET 上使用 Task.StartTask.Factory.StartNewTask.Run 并不是一个好的解决方案。

    在 ASP.NET 上使用 async/await 的全部目的是释放线程。但是,如果您 await 一个通过 Start/StartNew/Run 启动的任务,那么您通过占用同一线程池中的 另一个 线程来释放一个线程.在这种情况下,您不仅失去了async/await 的所有好处,而且实际上降低您的可伸缩性,因为您经常抛弃 ASP.NET 线程池试探法。

    two types of tasks,正如我在博客中所描述的:委托任务(代表在线程上执行的一些工作)和承诺任务(代表事件)。您应该避免在 ASP.NET 上使用委托任务,包括任何“已启动”的任务 (Start/StartNew/Run)。

    由于您返回的是IQueryable&lt;T&gt;,我假设您的实际底层操作是数据库查询。如果您使用的是 EF6,那么您将完全支持 asynchronous queries,它已通过 Promise 任务正确实现。

    【讨论】:

      【解决方案2】:

      你实际上并没有开始你的Task,所以它会等待一些永远不会开始的东西。

      改为使用Task.Factory.StartNew,它将同时创建和启动,或者调用Task#Start 并等待该调用。

      启动任务的方法概述:http://dotnetcodr.com/2014/01/01/5-ways-to-start-a-task-in-net-c/

      【讨论】:

      • 当然,启动任务有很多不同的方法。根据您的具体操作,它们可能会产生略微不同的效果,但在像这里这样的微不足道的例子中,无论哪种方式都应该没问题。最重要的方面实际上是开始任务。
      • 噢!谢谢。我误解了等待,我认为它也确保了任务运行。
      • @Chris:你应该接受斯蒂芬的回答而不是我的回答,这样更好。
      • @JeroenVannevel 已完成,我同意这是一个更好的答案,但您解决了我最初的愚蠢问题,再次感谢您。
      【解决方案3】:

      async/await那里绝对不需要,方法可以是这样的:

      public Task<IQueryable<int>> Get()
      {
          return Task.FromResult(new List<int>().AsQueryable());
      }
      

      如果你真的需要async,好吧,你总是可以写这样的:

      public async Task<IQueryable<int>> Get()
      {
          return await Task.FromResult(new List<int>().AsQueryable());
      }
      

      这将引入很少的开销(整个状态机将由编译器生成)。

      另外,正如其他人已经说过的,从async 方法返回的任务应该是hot(已启动)

      请记住,Task.FromResult 将返回已完成的任务,这种情况可以通过async/await 生成的代码进行优化,在这种情况下编写Task.Run 至少是奇怪的

      阅读Task-based Asynchronous Pattern了解更多详情

      【讨论】:

        猜你喜欢
        • 2012-08-08
        • 1970-01-01
        • 1970-01-01
        • 2017-05-19
        • 1970-01-01
        • 2013-11-14
        • 2014-10-22
        • 2015-07-21
        • 1970-01-01
        相关资源
        最近更新 更多