使用此代码可能导致IndexOutOfRange异常的原因是什么?

时间:2013-05-29 18:10:46

标签: c# sql-server-ce indexoutofboundsexception .net-1.1

最近,我在特定方法中获得了IndexOutOfRange异常。此函数中的新代码读取“csv”文件(使用扩展名“CSV”重命名的.txt文件)并对其进行解析;所以它必须是特定于该代码的代码,否则就是引发此异常的数据本身。

但它显然不是插入到数据库中,因为我在catch块中添加了一个MessageBox.Show(),并且我从未看到它。

public bool PopulatePlatypusItemsListAndInsertIntoPlatypusItemsTable(frmCentral fc)
{
    const int Platypus_ID_OFFSET = 0;
    const int Platypus_ITEM_ID_OFFSET = 1;
    const int ITEM_ID_OFFSET = 2;
    const int PACKSIZE_OFFSET = 3;

    bool ret = false;
    try
    {
        string dSQL;

        bool First = true;

        if (File.Exists(csvFilePathName))
        {
            int fzz = 0;

            dSQL = "DELETE FROM PlatypusItems";
            try
            {
                dbconn.DBCommand(dSQL, true);
            }
            catch
            {
                frmCentral.listboxMessage.TopIndex = frmCentral.listboxMessage.Items.Add(Convert.ToString(++frmCentral.lstMessageCount) +
                                                                                         ". Error processing PlatypusItem data from server");
            }

            SqlCeConnection conn = dbconn.GetConnection();
            if (conn != null && conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }
            SqlCeCommand cmd = conn.CreateCommand();

            cmd.CommandText = "INSERT INTO PlatypusItems ( PlatypusID, PlatypusItemID, ItemID, PackSize) VALUES (?, ?, ?, ?)";

            if (!ret) 
            {
                ret = true;
            }

            PlatypusItem DuckbillItm = new PlatypusItem();
            string thisLine;
            string[] arrLine;
            using (StreamReader sr = new StreamReader(csvFilePathName)) 
            {
                while (sr.Peek() >= 0) 
                {
                    thisLine = sr.ReadLine();
                    arrLine = thisLine.Split(',');
                    DuckbillItm.PlatypusID = arrLine[Platypus_ID_OFFSET];
                    DuckbillItm.PlatypusItemID = arrLine[Platypus_ITEM_ID_OFFSET];
                    DuckbillItm.ItemID = arrLine[ITEM_ID_OFFSET];
                    DuckbillItm.PackSize = Convert.ToInt32(arrLine[PACKSIZE_OFFSET]);

                    PlatypusItemList.List.Add(DuckbillItm);

                    dSQL = "INSERT INTO PlatypusItems (PlatypusID, PlatypusItemID, ItemID, PackSize) VALUES (" + DuckbillItm.PlatypusID + ",'" +
                        DuckbillItm.PlatypusItemID + "','" + DuckbillItm.ItemID + "'," + DuckbillItm.PackSize + ")";

                    if (!First)
                    {
                        cmd.Parameters[0].Value = DuckbillItm.PlatypusID;
                        cmd.Parameters[1].Value = DuckbillItm.PlatypusItemID;
                        cmd.Parameters[2].Value = DuckbillItm.ItemID;
                        cmd.Parameters[3].Value = DuckbillItm.PackSize.ToString();
                    }

                    if (First)
                    {
                        cmd.Parameters.Add("@PlatypusID", DuckbillItm.PlatypusID);
                        cmd.Parameters.Add("@PlatypusItemID", DuckbillItm.PlatypusItemID);
                        cmd.Parameters.Add("@ItemID", DuckbillItm.ItemID);
                        cmd.Parameters.Add("@PackSize", DuckbillItm.PackSize);
                        cmd.Prepare();
                        First = false;
                    }

                    if (frmCentral.CancelFetchInvDataInProgress)
                    {
                        return false;
                    }

                    try
                    {
                        // testing with these reversed: - either way, get the IndexOutOfRange exception...
                        //dbconn.DBCommand(cmd, dSQL, true);
                        dbconn.DBCommand(cmd, cmd.CommandText, true); //<-- If this works as well or better, dSQL is only there for the progress updating code below
                        // the first line is the legacy code; the second seems more sensible to me; both seem to work
                    }
                    catch (Exception x)
                    {
                        MessageBox.Show(string.Format("dbcommand exc message = {0}; PlatypusID = {1}; PlatypusItemID = {2}; ItemID = {3}; PackSize = {4}",      

                    x.Message, DuckbillItm.PlatypusID, DuckbillItm.PlatypusItemID, DuckbillItm.ItemID, DuckbillItm.PackSize));//TODO: Remove
                        frmCentral.listboxMessage.TopIndex =
                            frmCentral.listboxMessage.Items.Add(Convert.ToString(++frmCentral.lstMessageCount) +
                            ". Error processing Platypus Item data from server");
                    }

                    fzz += dSQL.Length; //<-- tried commenting this weird code out, but still get IndexOutOfRangeException

                    if (fzz > fc.ProgressChangedIndex)
                    {
                        fc.ProgressChangedIndex = fzz + fc.ProgressChangedIncrement;
                        if (((frmCentral.ProgressBar.progressBar1.Maximum/4) + (fzz*3) < frmCentral.ProgressBar.progressBar1.Maximum) &&
                            ((frmCentral.ProgressBar.progressBar1.Maximum/4) + (fzz*3) > frmCentral.ProgressBar.progressBar1.Value))
                        {
                            frmCentral.ProgressBar.progressBar1.Value = (frmCentral.ProgressBar.progressBar1.Maximum/4) + (fzz*3);
                            frmCentral.ProgressBar.progressBar1.Refresh();
                        }
                    }
                }
            }
        }
    }
    catch (Exception ex)
    {
        duckbilledPlatypiRUs.ExceptionHandler(ex, "PlatypusItemFile.PopulatePlatypusItemsListAndInsertIntoPlatypusItemsTable");
    }
    return ret;
}

我知道这段代码是不同风格的混合体;好的代码是我的,奇怪的代码是遗产(g,d&amp; r)

当然,我可以做到这一点,扫除地毯下的灰尘:

catch (Exception ex)
{
    if (ex.Message.IndexOf("IndexOutOfRange") < 0)
    {
        duckbilledPlatypiRUs.ExceptionHandler(ex, "PlatypusItemFile.PopulatePlatypusItemsListAndInsertIntoPlatypusItemsTable"); 
    }
}

...但我不知道IndexOutOfRangeException是否真的是一个严重的东西,在这个应用程序的内部造成混乱。

更新

我添加了这段代码:

if (arrLine[PLATYPUS_ID_OFFSET].Length > 10) //TODO: Remove?
            {
                                MessageBox.Show(string.Format("PLATYPUS_ID_OFFSET length should be 10; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
                                arrLine[PLATYPUS_ID_OFFSET] = arrLine[PLATYPUS_ID_OFFSET].Substring(0, 10);
                            }
                            if (arrLine[PLATYPUS_ITEM_ID_OFFSET].Length > 19)
                            {
                                MessageBox.Show(string.Format("PLATYPUS_ITEM_ID_OFFSET length should be 19; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
                                arrLine[PLATYPUS_ITEM_ID_OFFSET] = arrLine[PLATYPUS_ITEM_ID_OFFSET].Substring(0, 19);
                            }
                            if (arrLine[ITEM_ID_OFFSET].Length > 19)
                            {
                                MessageBox.Show(string.Format("ITEM_ID_OFFSET length should be 19; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
                                arrLine[ITEM_ID_OFFSET] = arrLine[ITEM_ID_OFFSET].Substring(0, 19);
                            }

...我从未见过那些MessageBox.Show(),所以我猜这不是引起问题的三个字符串值;也许是int(PackSize)。 PackSize永远不会超过Int32允许的范围; .NET 1.1中是否有TryParse()等价物?

更新2

从这里的异常中看到“IndexOutOfRange”,但从来没有看过MessageBox.Show()s:

try
{
    thisLine = sr.ReadLine();
    arrLine = thisLine.Split(',');
    if (arrLine[PLATYPUS_ID_OFFSET].Length > 10) //TODO: Remove?
    {
        MessageBox.Show(string.Format("PLATYPUS_ID_OFFSET length should be 10; was {0}", arrLine[PLATYPUS_ID_OFFSET].Length));
        arrLine[PLATYPUS_ID_OFFSET] = arrLine[PLATYPUS_ID_OFFSET].Substring(0, 10);
    }
    . . .
    DuckbillItm.PLATYPUSID = arrLine[PLATYPUS_ID_OFFSET];
    DuckbillItm.PLATYPUSItemID = arrLine[PLATYPUS_ITEM_ID_OFFSET];
    DuckbillItm.ItemID = arrLine[ITEM_ID_OFFSET];
    DuckbillItm.PackSize = Convert.ToInt32(arrLine[PACKSIZE_OFFSET]);
}
catch (Exception exc)
{
    MessageBox.Show(exc.Message);
}

更新3

毕竟这是糟糕的数据;其中一些行有四个逗号,而不是预期的三个。所以,我只是删除了那些行(在添加代码以检查数组的每个元素的大小,并在此之前修剪它们)并且运行正常。

1 个答案:

答案 0 :(得分:0)

我的初步猜测:如果您的输入.csv文件不正确,可能会导致arrLine[...]行之一(例如DuckbillItm.PlatypusID = arrLine[Platypus_ID_OFFSET])。做一个调试构建并将你的断点放在catch处理程序上,然后告诉我们&#34; ex.StackTrace&#34;说。