Прерывистое System.IndexOutOfRangeException при чтении поля из IDataReader - PullRequest
4 голосов
/ 19 января 2011

У меня очень странная проблема в коде, которую я не ожидал когда-либо потерпеть неудачу. Это веб-сайт с небольшим трафиком, но не такой большой, основанный на 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.IndexOutOfRangeException в System.Data.ProviderBase.FieldNameLookup.GetOrdinal (String fieldName) в System.Data.SqlClient.SqlDataReader.GetOrdinal (имя строки) в System.Data.SqlClient.SqlDataReader.get_Item (имя строки) в AspDotNetStorefront.ASPDNSFProfileProvider.GetPropertValuePairs (строка userName) в AspDotNetStorefront.ASPDNSFProfileProvider.GetPropertyValues ​​(контекст контекста Settings, параметры настройки свойства Properties, свойства) в System.Configuration.SettingsBase.GetPropertiesFromProvider (поставщик SettingsProvider) в System.Configuration.SettingsBase.GetPropertyValueByName (String propertyName) в System.Configuration.SettingsBase.get_Item (String propertyName) в System.Web.Profile.ProfileBase.GetInternal (String propertyName) в System.Web.Profile.ProfileBase.get_Item (String propertyName) в System.Web.Profile.ProfileBase.GetPropertyValue (String propertyName) в AspDotNetStorefront.SkinBase.OnPreInit (EventArgs e) в System.Web.UI.Page.PerformPreInit () в System.Web.UI.Page.ProcessRequestMain (логическое значение includeStagesBeforeAsyncPoint, логическое значение includeStagesAfterAsyncPoint)

Когда сайт падает, требуется перезапустить IIS, чтобы снова включить его. Это на Windows Server 2008 с .NET 3.5 и SQL 2008, все в актуальном состоянии. Машина является 64-битной, и в SQL Server включен 32-битный режим, а также пул приложений, который использует «классический конвейерный режим». Строка подключения

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

Любая помощь очень, очень ценится!

Ответы [ 2 ]

2 голосов
/ 06 сентября 2012

Так что после долгих поисков я наткнулся на ваш пост с той самой проблемой, которая у меня возникла. Я показываю эти сообщения своим друзьям здесь, на работе, и они признают, что это наш случай. Тогда я понимаю, что здесь недостаточно информации для решения моей проблемы. Поэтому я взял кое-что из сказанного здесь и еще немного обыскал.

Я сталкивался с этой публикацией: Индекс вне диапазона Исключение . Это хороший пост не только для NHibernate.

Я добавил Pooling=false; в строку подключения в моем web.config, а затем запустил серию тестов для загрузки сервера. Мы протестировали до 200% от нашей текущей максимальной загрузки посетителя, чтобы попытаться убить сервер с этой ошибкой. Ранее мы потерпели крах на уровне ниже 100%. Там не было ни одной ошибки. Я протестирую другой вариант, который был Enlist = false. Я не слышал об этом раньше.

Еще одно замечание: мы запускаем AspDotNetStoreFront в течение нескольких лет. Поэтому я вернулся, чтобы выяснить, почему в нашем последнем выпуске веб-сайта были все эти ошибки, а на старом сайте их не было. Оказывается, мы добавили pooling=false; ранее к большому успеху.

2 голосов
/ 19 января 2011

Я полагаю, что вы делитесь экземплярами устройства чтения данных между потоками. Убедитесь, что DB.GetRS во всех случаях возвращает новый экземпляр устройства чтения данных, а не возвращает общий экземпляр.

...