C#并行循环错误

4
有人可以帮忙吗?当我编写并运行这段代码时,程序显示错误提示“已经有一个与该命令关联的打开的DataReader,必须先关闭它”。这是我的代码。
Parallel.For(0, MthRange, i => {
    PSUpfrontFeeForMonth[i] = CommissionSummary
        .Where(s => s.TransDate == oReportCommonFilter.fromDate.AddMonths(i))
        .Sum(s => s.PSUpfrontFee);

    if (!PSUpfrontFeeForMonth[i].HasValue)
    {
        PSUpfrontFeeForMonth[i] = 0;
    }
});

Thanks.

Regards, Jane


3
为了易读性,您应该将任何代码标记为“代码示例”,可以通过选择代码片段并单击101010按钮来实现。 - Waqas
兄弟,通过在 Linq 查询中添加 ToList() 来进行急切评估,然后进行内存处理并行化。 - Jahan Zinedine
3个回答

4

将数据库查询并行化是完全错误的,原因如下:

  1. 每个处理器都会发出针对 SQL 的查询,因此将打开多个数据读取器 -> '错误'
  2. 没有实现性能提升,事实上程序变得更慢了,因为每个处理器都试图连接到数据库,并且没有实际进行并行处理,因为所有查询处理都在 SQL 中完成!所以在这种情况下,正常的串行查询更快。

1
如果您确实需要同时打开多个数据库连接(正如其他人所说的并不一定是一个好主意),那么通常可以在连接字符串中指定这一点。我使用这种方法的典型场景是使用DataReader从数据库表中流式传输行(因为我不知道需要多少行),然后需要对其他数据库表进行额外查询。我这样做而不是单个查询,因为它需要多个复杂的联接,而我的应用程序具有良好的缓存层以减少对数据库的查询。对于Microsoft SQL Server,您可以将MultipleActiveResultSets=True;添加到连接字符串中。

0

我猜测这可能与PSUpfrontFeeForMonth内部使用数据读取器有关。

由于我不知道它是如何工作的,所以我首先尝试的是在循环内初始化PSUpfrontFeeForMonth。也许这样可以确保每次迭代都有一个专用的数据读取器。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接