如何使用LINQ等待并行查询?

如何使用LINQ等待并行查询?,linq,asynchronous,async-await,parallel-extensions,Linq,Asynchronous,Async Await,Parallel Extensions,我有一个异步方法,可以查找数据库条目。它按名称进行过滤,因此是并行执行的一个实例 但是,我找不到一种简单的方法来同时支持并行执行和异步任务 以下是我所拥有的: private async Task<List<Item>> GetMatchingItems(string name) { using (var entities = new Entities()) { var items = from item in entities.Item.AsP

我有一个异步方法,可以查找数据库条目。它按名称进行过滤,因此是并行执行的一个实例

但是,我找不到一种简单的方法来同时支持并行执行和异步任务

以下是我所拥有的:

private async Task<List<Item>> GetMatchingItems(string name) {
    using (var entities = new Entities()) {
        var items =  from item in entities.Item.AsParallel()
               where item.Name.Contains(name)
               select item;
        return await items.ToListAsync(); //complains "ParallelQuery<Item> does not contain a definition for ToListAsync..."
    }
}
专用异步任务GetMatchingItems(字符串名称){
使用(变量实体=新实体()){
var items=来自entities.item.AsParallel()中的项
其中item.Name.Contains(名称)
选择项目;
return wait items.ToListSync();//抱怨“ParallelQuery不包含ToListSync的定义…”
}
}
当我删除
aspallel()
时,它将编译。A我不应该同时使用这两个功能?还是我理解错了什么

IHMO,两者都有意义:

  • aspallel()
    将指示数据库查询可能被拆分为同时运行的多个子查询,因为任何项的单个匹配不依赖于任何其他项UPDATE:在这个例子中是个坏主意,请参阅注释和答案
  • ToListAsync()
    将支持此方法的异步执行,以允许其他匹配方法(在其他数据上)立即开始执行

如何同时使用并行执行(使用LINQ)和异步任务?

嗯,你不能。这是两个不同的选项,它们并不在一起

您可以使用
Task.Run
async await
在多个
ThreadPool
线程上并行异步操作的同步部分(即第一个
await
之前的部分),但不在PLINQ中内置所有分区逻辑,例如:

var tasks = enumerable.Select(item => Task.Run(async () => 
{
    LongSynchronousPart(item);
    await AsynchronouPartAsync(item);
}));
await Task.WhenAll(tasks);

然而,在您的情况下(假设它是实体框架),使用PLINQ没有任何价值,因为没有实际的并行工作。查询本身在数据库中执行。

您不能,也不应该。PLINQ不用于数据库访问。数据库最了解如何并行化查询,并且使用普通LINQ自己就可以很好地并行化查询。PLINQ用于访问对象,例如在LINQ查询中执行计算代价高昂的计算,因此它可以在客户端对其进行并行化(而不是在服务器/数据库服务器端对其进行并行化)

更好的答案可能是: PLINQ用于跨多个线程分发计算密集型查询。 Async用于返回线程,以便其他人可以使用它,因为您将等待外部资源(数据库、磁盘I/O、网络I/O等)


Async PLINQ没有一个非常强大的用例,在这个用例中,您需要在等待时返回线程,并且需要进行大量计算。。。如果您正忙于计算,则需要该线程(或多个线程)。他们几乎完全处于优化的不同阶段。如果您需要这样的功能,有更好的机制,如任务等。

为什么要在数据库查询中使用
.aspallel()
?你认为它更快吗?如果这是你想要的,它会崩溃得更快。。。请阅读Stephen Cleary的博客…我想你是说这个:问题是你正试图让EF用parallism优化你的查询。这就是SQL server查询计划生成器的工作。在这种情况下,将查询拆分实际上会产生负面影响。@Aron我完全同意。所选的将实体转换为SQL的示例非常糟糕。不过,我将保留这个问题,以供将来参考。如果有人确实需要并行和异步功能,那么TPL数据流是一个很好的库。在这种情况下,PLINQ被op误用(我认为是误解了)。