在并行执行查询时出现“底层提供程序打开失败”的错误。

11
有时候,但不总是,我会遇到以下错误:"The underlying provider failed on open."
这是我的情况:
我有一个整数键的列表,并行处理它们以用作编译选择查询的参数。 我在 RIA domainservice 中使用它。
var queryResult = new List<int> {1, 2, 3}.AsParallel().Select(i => CompiledQueries.GetRecordByKey(this.ObjectContext, i)).ToList();

这就是编译后的查询语句:

public static IEnumerable<CompiledQueryResult> GetRecordByKey(MyEntities _context, int _key)
    {
        if (_getRecordByKey == null)
        {
            _getRecordByKey = CompiledQuery.Compile<MyEntities, int, IEnumerable<CompiledQueryResult>>
                ((ctx, key) =>
                    ctx.Records
                    .Where(r => r.Id == key)
                    .Select(r => new CompiledQueryResult
                    {
                        Id = r.ID,
                        Name = r.Name,
                        ...
                    })
                );
        }
        return _getRecordByKey.Invoke(_context, _key);
    }

我正在使用EF4和RIA(实际上将domainservice的ObjectContext传递给已编译查询方法),连接字符串包含了著名的MultipleActiveResultSets=True... 当MultipleActiveResultSets设置为false时,我立即收到错误。

此处使用的代码是真实代码的简化版本。我还传递了更多的键,因此有更多的并行查询。 有时我在内部异常中看到数据读取器被关闭,但状态仍为连接中..
我尝试扩大连接池大小,但没有成功。

有人有好的建议来解决这个问题吗?提前感谢。

2个回答

9

您是否尝试将连接字符串中的最小池大小选项设置为更高的值?

请尝试以下链接:MSDN


嗨Stephane,谢谢你的解决方案,我将最小池大小从0更改为1000,错误不再出现。我已经将最大池大小指定为1000,但我从未想过这个设置会解决问题。非常感谢..期待下一步 B) - ssanchezz23

2
在我的应用程序中也出现了同样的问题,最终发现是跨线程使用ObjectContext造成的。如果你在静态环境下同时从两个不同的线程执行查询(在同一个ObjectContext上),那么当第一个完成并关闭连接时,另一个正在尝试打开它,就会出现异常。
可笑的是我没有从之前的项目中吸取教训,在使用LinqToSQL时我们曾因为连接器的读取而引发了跨线程操作异常。不幸的是,ObjectContext没有以同样的方式阻止这种情况的发生。

这也是我的问题。我通过在执行一系列并行任务之前手动打开连接,然后在它们全部完成时关闭连接来解决了这个问题。https://msdn.microsoft.com/library/bb738698(v=vs.100).aspx - Whatever Man

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