2014-09-26 45 views
0

我想循環遍歷一個結果集,運行一個查詢來檢索數據,然後將該數據添加到列表中並將其返回。異步返回對象列表

的問題是,我試圖以異步方式做到這一點,我得到的錯誤:

'System.Collections.Generic.List' does not contain a definition for 'ToListAsync' and the best extension method overload 'System.Data.Entity.QueryableExtensions.ToListAsync(System.Linq.IQueryable)' has some invalid arguments

下面是方法的代碼:

public async Task<List<IHFData>> GetHFServiceData(string wtTransfereeId) 
{ 
    var hfDataList = new List<HFData>(); 

    Parallel.ForEach(aauthorizationList, item => 
    { 
     // code to retrieve data from database (truncated) 
     HFData hfData = Db.hfAuthorizations.AsNoTracking()....SingleOrDefault(); 

     hfDataList.Add(hfData); 
    } 

    return await hfDataList.ToListAsync(); // errors on this line 
} 

如何建立和回報我的列表異步?

+1

似乎'ToListAsync'是[實體框架方法(http://msdn.microsoft .com/en-us/library/dn220261(v = vs.113).aspx) – gunr2171 2014-09-26 18:03:23

回答

3

您的代碼有幾個巨大的問題。

首先,你在Parallel.ForEach裏面調用hfDataList.AddList<T>不是線程安全的,你不能調用Add without locking。

其次,因爲錯誤告訴你ToListAsync只能在具有接口IQueryable<T>的類型上調用,因此您在不實現該接口的List<T>上調用它。

做你的查詢正確的方法是

public Task<List<IHFData>> GetHFServiceData(string wtTransfereeId) 
{ 
    return Db.hfAuthorizations.AsNoTracking()....ToListAsync() 
} 

您需要修改什麼是你拿出來一次返回一組結果,而不是一個結果的....

另外await是不必要的,它是你的函數的最後一行,你可以返回任務directly並簡化生成的代碼並減少開銷。


如果你不能將其更改爲一組查詢(和你真的應該嘗試,這將大大提高你的表現),然後做你的老辦法的方式是放棄並行(實體框架不能處理它要麼),只是做一個正常foreach循環,然後在的SingleOrDefault的異步版本等待

public async Task<List<IHFData>> GetHFServiceData(string wtTransfereeId) 
{ 
    var hfDataList = new List<HFData>(); 

    foreach(var item in aauthorizationList) 
    { 
     // code to retrieve data from database (truncated) 
     HFData hfData = await Db.hfAuthorizations.AsNoTracking()....SingleOrDefaultAsync(); //This method is now async. 

     hfDataList.Add(hfData); 
    } 

    //just return the list when you are done. 
    return hfDataList; 
} 
+0

是的,我知道只需要一個linq查詢並調用ToListAsync();然而,我們使用foreach的原因是因爲對於一個查詢它太複雜了。是否有可能使用foreach構建並返回列表異步? – user1477388 2014-09-26 18:09:10

+1

@ user1477388我已經更新了答案,顯示瞭如何更接近您的舊方式來做到這一點。 – 2014-09-26 18:15:07

+0

有關這方面的問題:調試時,它看起來像代碼擊中foreach循環,然後直接進入返回行,因此'hfDataList'總是空的。你有什麼想法爲什麼它會跳過異步/添加代碼? – user1477388 2014-09-26 20:21:22

5

由於錯誤消息告訴您,沒有任何方法可以異步創建列表List。無論如何,你已經有了一份清單。

將項目添加到多個線程的列表中也是不安全的,就像您在平行foreach循環中所做的那樣。

您也不應該首先爲集合中的每個項目執行數據庫查詢。相反,您應該執行一個單一的數據庫查詢,根據您擁有的列表中的信息獲取所需的所有項目。該查詢應以ToListAsync的電話結束。

這裏也沒有必要有一個async方法,你可以直接返回ToListAsync的結果。