Click here to Skip to main content
16,022,402 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi,
Please consider the following code snippet:

C#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Data;

namespace ConsoleApplication4
{
    class Program
    {
        public DataTable DT { get; private set; }
        public const string PrimaeyKeyColumnName = @"PK";
        public const string ValueColumnName = @"Value";

        static void InitDT()
        {
            DT.Columns.Add(PrimaeyKeyColumnName, typeof(string));
            DT.Columns.Add(ValueColumnName, typeof(string));
            DT.PrimaryKey = new DataColumn[] { DT.Columns[PrimaeyKeyColumnName] };
        }

        void UpdateDT(string primaryKey, string value)
        {
            DataRow dr = null;
            lock (DT.Rows.SyncRoot)
            {
                if (DT.Rows.Contains(primaryKey))
                {
                    dr = DT.Rows.Find(primaryKey);
                    dr[ValueColumnName] = value;
                }
                else
                {
                    DT.Rows.Add(primaryKey, value);
                }
            }
            if (dr == null)
            {
                dr = DT.Rows.Find(primaryKey);
            }
            ProcessDR(dr);
        }

        void ProcessDR(DataRow dataRow)
        {
            // Do some processing based on some external conditions being true such as read dataRow[ValueColumnName] into some variable; that means within this method the read operation on the dataRow column cell will not always happen

            // Hitting this error SOMETIMES:

           //System.IndexOutOfRangeException: Index was outside the bounds of the array.
           //at System.Data.Common.StringStorage.Get(Int32 recordNo)
           //at System.Data.DataRow.get_Item(String columnName)
        }

        static void Main(string[] args)
        {
            InitDT();
            // Call UpdateDT() very frequently based on some trigger from the environment
        }
    }
}



Look at the ProcessDR method. I'm hitting that error infrequently / in a random manner (I know that's not the most scientific use of the word 'random').

I think, as a copy of the reference to the DataRow is passed to the ProcessDR method, and while ProcessDR accesses its column cells, sometimes the CLR throws that error because of the DataTable DT being in some "intermittent" state (remember the DataTable is being updated very frequently from a separate context).

Now 2 questions:
1. Is my understanding of the cause of the error correct?
2. Should I clone the DataRow before passing it to ProcessDR? If yes, what's the most performance-effective way to do that?

Regards
Posted
Updated 15-Dec-11 19:03pm
v2

1 solution

You are most probably trying toa ccess some members within the datarow which are possible null or empty.
Thus you get this error.

If you debug the method by stepping through the lines of code, I'm sure you will be able to figure out the problem and solve the issue.
 
Share this answer
 
Comments
kjain18 16-Dec-11 1:11am    
I guess you're referring to "NullPointerException" but I'm faced with the "IndexOutOfRangeException"...

Also, stepping through the code is not an option.

Regards
Abhinav S 16-Dec-11 2:50am    
You should be able to figure out the IndexOutOfRangeException by debugging as well.

kjain18 16-Dec-11 3:10am    
@Abhinav, due to some practical constraints (cannot disclose them) I can only log information; I cannot step through the running code...
Abhinav S 16-Dec-11 3:28am    
Ok can you atleast look at the code?
If you can, check if you are using a loop in which or direct array access where you provided a count which may not exist.
E.g. arr[15] = "element"; where arr size may only be 4.
kjain18 16-Dec-11 3:35am    
I'm the developer of the code.

As my sample code demonstrates, the size of the DataRow is fixed, and I access the cell element by the corresponding ColumnName. The row is added/updated to the table before it's passed to ProdessDR for processing.

Regards

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900