2017-06-22 45 views
0

我已經做了一些代碼實現一些Web API。 此API方法返回Foo Table的最後一條記錄。在ASP.NET中,爲什麼DbSet.LastAsync()不存在?

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); 
    } 
} 

我想使此API異步,但沒有LastAsync()方法。 爲什麼以及如何解決? 在此先感謝。

回答

5

在ASP.NET你不應該使用Task.Run:

異步和等待在ASP.NET都關於I/O。他們在 讀寫文件,數據庫記錄和REST API方面非常出色。但是, 它們不適合CPU限制的任務。您可以通過等待Task.Run啓動一些背景 工作,但這樣做沒有意義。實際上, 實際上會通過干擾 ASP.NET線程池啓發式來傷害您的可伸縮性。如果你在ASP.NET上有CPU綁定的工作,最好的辦法就是直接在請求 的線程上執行它。作爲一般規則,請勿將工作排隊到 ASP.NET上的線程池。

Async Programming : Introduction to Async/Await on ASP.NET

不過,這並不意味着你不能使用異步和等待在ASP.NET中的I/O(這就是你想要的)只使用真正的異步方法,而不是假的異步對同步方法的封裝(只會將工作推送到其他ThreadPool線程中,並且您將not gain any performance benfit from it)。

既然你沒有LastAsync方法EF我建議你使用排序依據訂購您的收藏,只要你想和使用FirstAsync方法(或支持拉姆達謂詞FirstAsync過載),而不是使用Last方法,FirstAsync是EF中支持的真正的異步I/O方法。

有關何時適合使用Task.Run的更多信息,請參見Stephen Cleary博客中的Task.Run Etiquette Examples: Don't Use Task.Run in the Implementation文章。

您的問題爲什麼沒有LastAsync方法首先應該被引導到微軟的團隊,該團隊需要EF api,但我的猜測是他們沒有打算實現它,因爲它很容易實現按照我的建議,在功能上與FirstAsync方法。

-5

有關如何解決呢

可以使用

await Task.Run(()=>db.Foo.Last()); 
+0

感謝您的回答! –

+4

但是你不應該在ASP.NET中。它只會吃資源,表現最差。 –

+2

你應該絕對不這樣做。這將會無用地燒燬資源。這沒有任何好處。 –

0

一個代碼的工作版本是這樣的:

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.OrderByDesc(x=> x.Timestamp).FirstOrDefaultAsync(); 
     if (foo == null) 
     { 
      return NotFound(); 
     } 
     return Ok(foo); 
    } 
} 

末等不針對EF IQueryable的工作,因爲SQL不具有等效的命令

相關問題