![](/img/trans.png)
[英]How to return an action result of async Task<IEnumerable<SomeClass>>?
[英]return IEnumerable as result of async function calls
我有一個獲取一系列項目的函數:
List<MyType> GetPage(int pageNr) {...}
要獲得所有可用的物品,您可以執行以下操作:
IEnumerable<MyType> FetchMyItems()
{
int pageNr = 0;
var fetchedItems = GetPage(pageNr);
while (fetchedItems.Any()
{ // there are items to return
// yield return the fetched items:
foreach (var fetchedItem in fetchedItems)
yield return fetchedItems;
// get the next page
++pageNr;
fetchedItems = GetPage(pageNr)
}
}
使用此方法,我的用戶將不再需要每頁獲取項目,如果他們只需要少量項目,則僅獲取第一頁。 需要更多項目時將自動獲取更多頁面。 缺點當然是我有時會再拿一些不使用的物品。
所以我有以下GetPage:
async Task<List<MyType>> GetPageAsync(int pageNr) {...}
據我從IEnumerable了解到的是,它不會創建結果序列,而只會創建枚舉該序列的可能性。
這種枚舉是使用'foreach'顯式完成的,或者使用諸如'ToList','ToArray'的LINQ函數隱式完成的,還可以使用'FirstOrDefault','Any', Sum
類的函數進行隱式枚舉。
var fetchItemTasks = FetchMyItemsAsync();
foreach (var fetchItemTask in fetchedItemTasks)
{
MyType fetchedItem = await fetchItemTask;
Process(fetchedItem);
}
或者,如果您執行此低級別操作:
var myitemsEnumerable = fetchMyItemsAsync();
// don't await yet, only create the possibility to enumerate
var enumerator = myItemsEnumerable.GetEnumerator();
while (enumerator.MoveNext())
{ // there is an item available in current:
Task<MyType> task = enumerator.Current;
return task;
}
看來,該函數似乎不應該返回Task<IEnumerable<MyType>>
而是IEnumerable<Task<MyType>>
,如果要訪問元素,則必須等待。
因此,返回可能枚舉等待項的功能的函數本身並不異步。 您不必等待枚舉,可以在不訪問數據庫等慢速提供程序的情況下創建該枚舉。 可枚舉順序中的項目是可以等待的:
IEnumerable<Task<MyType>> FetchMyItems()
{
int pageNr = 0;
Task<List<MyType>> fetchItemTask = GetPageAsync(pageNr);
現在? 如果我await fetchItemTask
,則該項目已經是本地的,不再需要等待。 如果我fetchItemTask.Wait()
,則該函數將阻塞。
您的異步/等待模式實現看起來不正確。
GetPageAsync
簽名很好:
async Task<List<MyType>> GetPageAsync(int pageNr) {...}
現在,如果要異步調用此方法,則必須使用await
關鍵字,它將暫停執行方法並將控制權返回給其調用者,直到GetPageAsync
結果准備就緒:
List<MyType> items = await GetPageAsync(pageNr);
要么
Task<List<MyType>> getPageTask = GetPageAsync(pageNr);
// Some other stuff
List<MyType> items = await getPageTask;
但請注意, await
關鍵字只能在本身是async
的方法內使用。
可能我沒有意識到您的應用程序異步模型的全部概念,但是無論如何,我建議您先閱讀有關異步編程與異步/等待的MSDN文章 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.