如何使用 LINQ 等待 ParallelQuery?

Mar*_*cel 4 linq asynchronous parallel-extensions async-await

我有一个异步方法,应该查找数据库条目。它按名称过滤,因此是并行执行的候选者。

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

这是我所拥有的:

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..."
    }
}
Run Code Online (Sandbox Code Playgroud)

当我删除它时AsParallel(),它将编译。AI 不应该同时使用这两个功能吗?还是我理解有问题?

IHMO,两者都有道理:

  • AsParallel()表示数据库查询可能会分成几个同时运行的子查询,因为任何项目的单独匹配都不依赖于任何其他项目。更新:这个例子中的坏主意,请参阅评论和答案!
  • ToListAsync()将支持此方法的异步执行,以允许其他匹配方法(在其他数据上)立即开始执行。

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

Rob*_*Kee 5

你不能,也不应该。PLINQ 不适用于数据库访问。数据库最了解如何并行化查询,并且可以使用普通 LINQ 自行完成此操作。PLINQ 用于访问对象,例如在 LINQ 查询中进行计算量大的计算,因此它可以在客户端并行化(而不是在服务器/数据库服务器端并行化)。

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

Async PLINQ 没有一个非常强大的用例,您希望在等待时返回线程,并且您有很多计算要做...如果您忙于计算,则需要线程(或多个线程)。他们几乎完全处于不同的优化目的。如果您需要这样的东西,有更好的机制,例如任务等。

  • 如果有人确实需要并行*和*异步功能,TPL Dataflow 是一个很好的库。在这种情况下,PLINQ 被操作者误用(我认为是误解)。 (2认同)