Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intermittent System.IndexOutOfRangeException when reading a field from IDataReader

I have a very weird problem in code that I would not expect to ever fail. It is a website with some traffic but not that huge based on AspDotNetStoreFront. Site intermittently crashes when trying to read a database field from a reader. This happen on various places on the website. An example of such code is below on the line with 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;
    }

It is standard use of SqlClient and I can't see anything wrong with it. Stack trace of the error is this:

System.IndexOutOfRangeException at System.Data.ProviderBase.FieldNameLookup.GetOrdinal(String fieldName) at System.Data.SqlClient.SqlDataReader.GetOrdinal(String name) at System.Data.SqlClient.SqlDataReader.get_Item(String name) at AspDotNetStorefront.ASPDNSFProfileProvider.GetPropertValuePairs(String userName) at AspDotNetStorefront.ASPDNSFProfileProvider.GetPropertyValues(SettingsContext context, SettingsPropertyCollection settingsProperties) at System.Configuration.SettingsBase.GetPropertiesFromProvider(SettingsProvider provider) at System.Configuration.SettingsBase.GetPropertyValueByName(String propertyName) at System.Configuration.SettingsBase.get_Item(String propertyName) at System.Web.Profile.ProfileBase.GetInternal(String propertyName) at System.Web.Profile.ProfileBase.get_Item(String propertyName) at System.Web.Profile.ProfileBase.GetPropertyValue(String propertyName) at AspDotNetStorefront.SkinBase.OnPreInit(EventArgs e) at System.Web.UI.Page.PerformPreInit() at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)

When the site crashes it requires to restart IIS to bring it back on. It is on Windows Server 2008 with .NET 3.5 and SQL 2008, all up to date. The machine is 64 bit and SQL Server has 32-bit mode enabled as well as the application pool that uses "classic pipeline mode". THe connection string is

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

Any help very very appreciated!!

like image 582
David Avatar asked Jan 19 '11 10:01

David


2 Answers

I would guess that you are sharing instances of a datareader between threads. Make sure that DB.GetRS is returning a new instance of a datareader in all cases, and not returning a shared instance.

like image 152
Phil Sandler Avatar answered Oct 13 '22 22:10

Phil Sandler


So after much searching, I come across your post with the exact problem that I have. I show the posting around to my friends here at work and they acknowledge that this is our case. Then I realize that there is not enough information here to solve my problem. So I took some of what is said here and searched some more.

I came across this posting: Index Out Of Range Exception. It is a good post not just for NHibernate.

I added Pooling=false; to my connection string in my web.config and then started a series of tests to load the server down. We tested to 200% of our current max visitor load to try to kill the server with this error. Previously, we would crash at below 100%. There was not a single error. I will test the other option which was Enlist=false. I haven't heard of this before.

One further note, we have been running AspDotNetStoreFront for several years. So I went back to find out why our latest website release was having all of these errors and the old site didn't have the errors. Turns out we had added pooling=false; previously to great success.

like image 40
CaptainBli Avatar answered Oct 13 '22 22:10

CaptainBli