2015-11-04 37 views
4

我們最近開發了一個ASP.Net WebAPI2,它使用跨各層的同步調用,如下所示。如何修復我的WebAPI2控制器以使用異步Task for scability

enter image description here

現在我才知道,那最好使用穩定的原因Async Task的方法,但是隨着代碼爲大部分功能使用同步調用已經開發,我想知道什麼是轉換的最佳方式我有的電話。

說這是怎麼我的代碼最初寫的:

[Route("user/{userId}/feeds ")] 
[HttpGet] 
public IEnumerable<NewsFeedItem> GetNewsFeedItemsForUserAsync(string userId) 
{ 
    return newsFeedService.GetNewsFeedItemsForUser(userId); 
} 

我可以將此轉換爲這樣的事情:

[Route("user/{userId}/feeds ")] 
[HttpGet] 
public async Task<IEnumerable<NewsFeedItem>> GetNewsFeedItemsForUserAsync(string userId) 
{ 
    return await Task.Run(()=>newsFeedService.GetNewsFeedItemsForUser(userId)); 
} 

但是,如果我理解正確的話,我不認爲將幫助我擴大我的網站,因爲它仍然會使用線程池線程。

我看到修改所有圖層和所有要使用的功能的唯一其他選項async,但這似乎很多工作。

所以我想知道這裏有沒有人需要進行類似的練習,解決這個問題的最好方法是什麼。

問候 基蘭

+0

'異步'一路... –

+0

最好的方法是'newsFeedService'提供'async'方法,所以你可以從控制器中'等待'它。同時,'newsFeedService'應該有一個'async' DAO/Repository,它應該有'async'持久性策略,它應該有'async'方法,它應該與底層數據庫異步通信......(重點是你會必須將所有執行流轉換爲'async') –

+0

如果'await'是該方法的最後一個語句,則可以將其刪除。刪除它後,如果你沒有'await'語句,你可以刪除'async'關鍵字。 –

回答

3

我看到修改的所有層和所有功能 使用異步但像很多工作接縫唯一的選擇。

你說得對,寫了一個公開真正的異步方法,一個全新的數據訪問層是艱苦的工作,因爲它通常需要從根本上重新寫入。但是,如果您知道實際上需要可擴展性,並且您已將其識別爲當前的瓶頸,那麼它最終會值得。

包裝一下你在Task.Run代碼將沒有受益,因爲你說你自己,因爲什麼異步不正是處於空閒的線程池線程,同時完成IO,在這裏你實際上消耗另一個線程,比其他一個是ASP.NET運行時已經提供的。

總而言之,要做到這一切並非易事,必須重新將異步終端寫入/添加到調用代碼中。

+0

ADO.NET和Entity Framework都提供異步方法。改變數據層可能並不那麼困難 –

+0

@Yuval Itzchakov:謝謝,看起來只有這樣才能做到這一點。我是多麼希望如果有一種方法來標記編譯器(比如說使用屬性)在完整的調用鏈中等待任何I/O調用:) – Kiran