在ASP.NET中,为什么DbSet.LastAsync()不存在?

Cha*_*Kim 0 asp.net async-await asp.net-web-api entity-framework-6

我已经制作了一些代码来实现一些Web API.此API方法返回Foo Table的最后一条记录.

public class FooController : ApiController
{
    private FooContext db = new FooContext();

    // GET: api/Foo
    [ResponseType(typeof(Foo))]
    public async Task<IHttpActionResult> GetLastFoo()
    {
        Foo foo = await db.Foo.Last();
        if (foo == null)
        {
            return NotFound();
        }
        return Ok(foo);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想让这个API异步,但没有LastAsync()方法.为什么以及如何解决它?提前致谢.

Yuv*_*hap 5

您不应该在ASP.NET中使用Task.Run:

ASP.NET上的异步和等待都是关于I/O的.他们擅长阅读和编写文件,数据库记录和REST API.但是,它们不适合CPU绑定任务.您可以通过等待Task.Run开始一些后台工作,但这样做没有意义.事实上,这实际上会通过干扰ASP.NET线程池启发式来损害您的可伸缩性.如果你有关于ASP.NET的CPU限制工作,最好的办法是直接在请求线程上执行它.作为一般规则,不要将工作排队到ASP.NET上的线程池.

异步编程:ASP.NET上的Async/Await简介

它仍然不意味着你不能在ASP.NET中使用异步和等待I/O(这就是你想要的)只是使用真正的异步方法而不是假同步方法的异步包装(这只会将工作推入其他ThreadPool线程,你不会从中获得任何性能好处).

由于您在EF中没有LastAsync方法,我建议您使用OrderBy根据需要对集合进行排序,并使用FirstAsync方法(或支持lambda谓词的FirstAsync重载)而不是使用Last方法,FirstAsync是真正的异步I/EF支持的O方法.

有关何时使用Task.Run的更多信息可以在Task.Run Etiquette示例中找到:不要在Stephen Cleary的博客的实施文章中使用Task.Run.

你的问题为什么首先没有LastAsync方法应该直接指向微软设计EF api的团队,但我的猜测是他们不打算实现它,因为使用FirstAsync方法在功能上很容易实现正如我所说.