2014-09-26 43 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的结果。