【发布时间】:2015-06-08 10:04:10
【问题描述】:
我正在开发一个使用静态全局 DataContext 的项目(不推荐,但目前很难更改)。我目前需要通过并行化一些独立的功能来提高某些部分的性能。由于 DataContext 不是线程安全的,我不能在新创建的线程中使用它。因此,我在每个线程内部创建了一个新的 DataContext,并在线程结束时将其释放。
新的数据上下文一切正常,但我有一个问题,该函数的输入之一是附加到全局数据上下文的 IQueryable。运行该方法将导致“已经有一个打开的 DataReader 与此命令关联,必须先关闭。”的异常。
问题是,我如何能够使用新的数据上下文而不是更改的数据上下文来运行 IQueryable。
请在下面找到线程的示例代码:
var myQueryable = Global.DataContext.Customers.Where(a => a.Age <12);
ParallelLoopResult threads = Parallel.ForEach(groups, group =>
{
DataContext ctx = new DataContext(Const.ConnectionString);
myFunction(myQueryable);
ctx.Dispose();
});
不幸的是,在线程内部重写 myQueryable 的选项非常困难,因为生成它需要大量的逻辑。将其转换为列表然后传递它也不是一种选择,因为查询会返回数千个条目,并且会对性能产生负面影响。
非常感谢任何帮助
【问题讨论】:
-
为什么不创建一个新的、相同的 IQueryable?将其创建封装在一个接受上下文作为参数的函数中,并从您想要的任何位置创建查询。此外,可查询对象是 将在特定上下文中运行的查询——您不能更改它们的父对象。这就是为什么您应该不拥有全局上下文的非常严重的原因之一
-
我完全同意你的看法。但是以前的开发人员选择了这种方法,并且生成 IQueryable 的部分是紧密耦合的。所以我希望有一种方法可以将查询附加到不同的 DataContext 作为最简单和最快的解决方法。但似乎唯一的方法是更改该代码以接受 DataContext 作为参数。谢谢
-
Queryables 是可以执行的查询,它们不是查询定义。顺便说一句,您为什么要尝试并行执行多个 Queryable?这不会使任何东西运行得更快(相反)。您是否有一个您认为可以通过并行解决的性能问题?编写良好的 SQL 语句和适当的索引会更有效(效率高出数千倍)
-
也许我对并行性部分提高了我的场景中的性能是错误的,但这只是一个临时解决方案。当前代码在 for 循环中运行 n 个读取查询。每个查询需要一秒钟的时间来运行。所以所有查询的总和很多。我在这里尝试通过单独运行独立查询来快速加快速度,直到我们重新编写函数。重写整个部分是可行的方法,但需要数周时间。我只是希望快速改进。
-
您可能还想考虑将多个查询批处理在一起,以避免网络往返成本。如果每个查询需要 1 秒,则网络成本是一个重要问题。在 EF 中,您可以使用 EntityFramework.Extended 包和未来查询来执行此操作。它还支持批量更新/删除
标签: c# multithreading linq-to-sql task-parallel-library datacontext