异步控制器方法没有返回

Chr*_*ris 0 c# asp.net async-await asp.net-web-api

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

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

但这种方法很好:

public IQueryable<int> Get()
{
    return new List<int>().AsQueryable();
}
Run Code Online (Sandbox Code Playgroud)

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

Ste*_*ary 6

正如另一个答案所指出的那样,控制器未完成的原因是因为任务未启动.但是,在ASP.NET上使用Task.Start,Task.Factory.StartNew或者Task.Run不是一个好的解决方案.

在ASP.NET 上使用async/ 的全部意义await在于释放一个线程.但是,如果您await是通过Start/ StartNew/ 启动的任务Run,那么您将通过从同一个线程池中占用另一个线程来释放一个线程.在这种情况下,您不仅失去了async/的所有好处await,而且实际上通过定期抛弃ASP.NET线程池启发式来降低可伸缩性.

正如我在博客中描述的那样,有两种类型的任务:委托任务(代表在线程上执行的一些工作)和Promise Tasks(代表一个事件).您应该避免在ASP.NET上委派任务,包括"已启动"(Start/ StartNew/ Run)的任何任务.

由于您正在返回IQueryable<T>,我假设您的实际基础操作是数据库查询.如果您正在使用EF6,那么您完全支持异步查询,这些查询可以通过Promise Tasks正确实现.