【问题标题】:Intermittent System.IndexOutOfRangeException when reading a field from IDataReader从 IDataReader 读取字段时出现间歇性 System.IndexOutOfRangeException
【发布时间】:2011-01-19 10:16:33
【问题描述】:

我在代码中有一个非常奇怪的问题,我不希望它会失败。这是一个基于 AspDotNetStoreFront 的网站,有一些流量,但不是很大。尝试从阅读器读取数据库字段时,站点间歇性崩溃。这发生在网站上的各个地方。此类代码的示例如下,object pValue = rs["PropertyValueString"];

private Dictionary<string, object> GetPropertValuePairs(string userName)
    {
        string query = string.Format("select PropertyName, PropertyValueString from dbo.profile with(nolock) where CustomerGUID = {0} and StoreID = {1}", DB.SQuote(userName),AppLogic.StoreID());

        Dictionary<string, object> propertyValues = new Dictionary<string, object>();

        using (SqlConnection conn = new SqlConnection(DB.GetDBConn()))
        {
            conn.Open();

            using (IDataReader rs = DB.GetRS(query, conn))
            {
                while (rs.Read())
                {
                    string pName = DB.RSField(rs, "PropertyName");
                    object pValue = rs["PropertyValueString"];

                    if (propertyValues.ContainsKey(pName) == false)
                    {
                        propertyValues.Add(pName, pValue);
                    }
                }

                rs.Close();
                rs.Dispose();
            }
            conn.Close();
            conn.Dispose();
        }

        return propertyValues;
    }

这是 SqlClient 的标准用法,我看不出它有什么问题。错误的堆栈跟踪是这样的:

System.Data.ProviderBase.FieldNameLookup.GetOrdinal 处的 System.IndexOutOfRangeException(字符串字段名) 在 System.Data.SqlClient.SqlDataReader.GetOrdinal(字符串名称) 在 System.Data.SqlClient.SqlDataReader.get_Item(字符串名称) 在 AspDotNetStorefront.ASPDNSFProfileProvider.GetPropertValuePairs(字符串用户名) 在 AspDotNetStorefront.ASPDNSFProfileProvider.GetPropertyValues(SettingsContext 上下文,SettingsPropertyCollection settingsProperties) 在 System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider 提供者) 在 System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName) 在 System.Configuration.SettingsBase.get_Item(字符串属性名称) 在 System.Web.Profile.ProfileBase.GetInternal(字符串属性名称) 在 System.Web.Profile.ProfileBase.get_Item(字符串属性名称) 在 System.Web.Profile.ProfileBase.GetPropertyValue(字符串属性名称) 在 AspDotNetStorefront.SkinBase.OnPreInit(EventArgs e) 在 System.Web.UI.Page.PerformPreInit() 在 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

当网站崩溃时,它需要重新启动 IIS 才能重新启动。它在带有 .NET 3.5 和 SQL 2008 的 Windows Server 2008 上,都是最新的。该机器是 64 位的,SQL Server 启用了 32 位模式以及使用“经典管道模式”的应用程序池。连接字符串是

 <add name="PrimaryConnectionString" connectionString="data source=XXXX;database=XXXX;Integrated Security=True;Application Name=XXXX;MultipleActiveResultSets=true" />

非常感谢任何帮助!

【问题讨论】:

  • 在这里看到同样的东西。我们相信运行 32 位模式 ASP.NET2.0 SP2 的 64 位机器存在某种兼容性问题。如果我们找到解决方案,将会更新。
  • 我遇到了同样的问题,您找到解决方案了吗? @johnny g,问题是有点差异吗?大卫,这是一个多线程应用程序吗?
  • 马克我想,我在下面有你的答案。过去对我们来说是个问题。让我知道您的想法以及我的解决方案是否有帮助。

标签: c# sql datareader sqlclient aspdotnetstorefront


【解决方案1】:

我猜你是在线程之间共享数据读取器的实例。确保 DB.GetRS 在所有情况下都返回数据读取器的新实例,而不是返回共享实例。

【讨论】:

  • 这是 DB.GetRS 的代码: using (SqlCommand cmd = new SqlCommand(Sql, dbconn)) { return cmd.ExecuteReader();没有什么不妥。谢谢 }
  • 多线程应用的评论让我产生了一些思考。数据跨过重用的池线程。于是我又去搜索了一些。
【解决方案2】:

所以经过大量搜索后,我发现您的帖子与我遇到的确切问题有关。我把这个帖子展示给我工作的朋友,他们承认这是我们的情况。然后我意识到这里没有足够的信息来解决我的问题。所以我把这里所说的一些东西拿来搜索了一些。

我看到了这个帖子:Index Out Of Range Exception。这是一篇好文章,不仅适用于 NHibernate。

我在web.config 的连接字符串中添加了Pooling=false;,然后开始了一系列测试以加载服务器。我们测试了当前最大访问者负载的 200%,以尝试使用此错误终止服务器。以前,我们会在 100% 以下崩溃。没有一个错误。我将测试另一个选项 Enlist=false。我以前没听说过。

进一步说明,我们已经运行 AspDotNetStoreFront 好几年了。所以我回去找出为什么我们最新的网站版本有所有这些错误,而旧网站没有这些错误。原来我们之前添加了pooling=false; 并取得了巨大的成功。

【讨论】:

  • 你还有同样的问题还是已经解决了?我会死知道如何解决此类问题,现在我将添加 Pooling=false;并将检查结果,您上次写此评论后是否有任何错误?
  • 我们不再有这个问题。我们已经这样做了很长一段时间了。
  • 谢谢,我已经添加了 pooling=false;到我的连接字符串,这是一个很好的解决方案,之后我不再面临这个问题,没有stackoverflow的生活!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多