C# WPF 应用程序 - 在运行时修改数据表时出现问题 - System.ArgumentOutOfRangeException

C# WPF App - Problem with modifying datatable during runtime - System.ArgumentOutOfRangeException

我需要这方面的帮助。现在已经 2 天了,还没有弄清楚根本原因。 在我的应用程序中,我将一定数量的行添加到 DataTable 并通过 DataGrid 显示它。

定时器设置为按一定间隔(当前设置为 10 秒)做一些工作:

将计算机列表添加到 DataTable 并将它们显示到 DataGrid 中效果很好。 问题发生在我按下触发计时器的“开始”按钮后。发生错误所需的时间取决于向 DataTable 添加了多少行。

对于下面发布的所有信息,我们深表歉意。我开始感到沮丧。希望有人能发现明显的问题并帮助我解决这个问题。我已经注释掉了一些代码以缩小问题所在的范围。

出于测试目的,当我单击“测试”按钮时,创建了初始数据表并用空 table 填充了 DataGrid。

void FillDataGrid()
        {

            try
            {
                ds.ReadXml(@"C:\Temp\ToastData.ds");                
                gridToastItems.ItemsSource = ds.Tables[0].DefaultView;
                
            }
            catch (Exception ioException)
            {

                dt.Clear();
                DataColumn column;

                //ID Column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.Int32");
                column.ColumnName = "id";
                column.ReadOnly = true;
                column.Unique = true;
                column.AutoIncrement = true;
                dt.Columns.Add(column);

                //// Make the ID column the primary key column.
                //DataColumn[] PrimaryKeyColumns = new DataColumn[1];
                //PrimaryKeyColumns[0] = dt.Columns["id"];
                //dt.PrimaryKey = PrimaryKeyColumns;

                // Hostname column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "hostname";
                column.Caption = "Hostname";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);

               
                // Online column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.Boolean");
                column.ColumnName = "online";
                column.Caption = "Online";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);

                // OS Version column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "osversion";
                column.Caption = "OS Version";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);

                // Lockscreen status column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "lockscreen";
                column.Caption = "Lockscreen Status";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);

                // Toast type column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "toasttype";
                column.Caption = "Toast Type";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);

                // Schedule column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "schedule";
                column.Caption = "Schedule";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);

                // Result column
                column = new DataColumn();
                column.DataType = System.Type.GetType("System.String");
                column.ColumnName = "status";
                column.Caption = "Status";
                column.ReadOnly = false;
                column.Unique = false;
                column.AutoIncrement = false;
                dt.Columns.Add(column);


                ds.Tables.Add(dt);

                gridToastItems.ItemsSource = dt.DefaultView;


                //DataColumn hostname = new DataColumn("Hostname", typeof(string));
                //DataColumn online = new DataColumn("Online", typeof(bool));
                //DataColumn osversion = new DataColumn("OS Version", typeof(string));
                //DataColumn lockscreen = new DataColumn("Lockscreen Status", typeof(string));
                //DataColumn toastname = new DataColumn("Toast Type", typeof(string));
                //DataColumn schedule = new DataColumn("Schedule", typeof(string));
                //DataColumn result = new DataColumn("Result", typeof(string));

                //dt.Columns.Add(hostname);
                //dt.Columns.Add(online);
                //dt.Columns.Add(osversion);
                //dt.Columns.Add(lockscreen);
                //dt.Columns.Add(toastname);
                //dt.Columns.Add(schedule);
                //dt.Columns.Add(result);
                //dt.AcceptChanges();
                //gridToastItems.ItemsSource = dt.DefaultView;
                //ds.Tables.Add(dt);
                //ds.AcceptChanges();
            }

        }

从第二种形式将计算机添加到 DataTable:

private void AddToastEntries()
        {
           
            bool exceptionCaught = false;   
            try
            {
               
                int lineCount = txtComputerNames.LineCount; //iterator for number of computernames in the textbox
                if (lineCount > 1)
                {

                    for (int i = 0; i < lineCount; i++)
                    {

                        string currentLine = txtComputerNames.GetLineText(i).ReplaceLineEndings("");

                        //Adding a new toast entry for each computername listed in the textbox
                        if (currentLine != "")
                        {

                            
                            DataRow firstRow = MainWindow.ds.Tables[0].NewRow();
                            firstRow["hostname"] = currentLine;
                            firstRow["online"] = false;
                            firstRow["osversion"] = "";
                            firstRow["lockscreen"] = "";
                            firstRow["toasttype"] = "Windows Update";
                            firstRow["schedule"] = SelectedDateTime();
                            firstRow["status"] = "Pending";
                            MainWindow.ds.Tables[0].Rows.Add(firstRow);
                            //MainWindow.ds.Tables[0].AcceptChanges();
                            //MainWindow.ds.AcceptChanges();

                        }
                    }
                }
            }catch(Exception newToastEntriesException)
            {
                exceptionCaught = true;
            }

           if(exceptionCaught)
            {
                MessageBox.Show("Failed to add current selection to schedule\n Check that a valid date and time is selected", "Error" ,MessageBoxButton.OK ,MessageBoxImage.Asterisk);
            }
           
        }

这是我单击“开始”按钮时来自上面 window 的代码 运行

private async void timer_Tick(object sender, EventArgs e)
{

           await Task.Run(() => ProcessToastMessages());

}


    private void ProcessToastMessages()
    {

        WindowsToasts.WindowsToast windowsUpdateToast = new WindowsToast(); //creating a new instance of a toast message
        int rowCount = 0;
        rowCount = ds.Tables[0].Rows.Count;
        for (int i = 0; i <= (rowCount - 1); i++)
        {
          
                DateTime scheduledTime = DateTime.Now;

            //try
            //{

                DateTime.TryParse(ds.Tables[0].Rows[i]["schedule"].ToString(), out scheduledTime); //Converting the string value of date in the to a type of DateTime
                string currentStatus = ds.Tables[0].Rows[i]["status"].ToString();
                    if ((scheduledTime.Ticks < DateTime.Now.Ticks) && currentStatus == "Pending")
                    {
                        string computerName = ds.Tables[0].Rows[i]["hostname"].ToString(); // Gets the computername in currentrow

                   
                    bool isOnline = ComputerFuncs.ComputerOnline(computerName); // Checking if computer is online (Ping)

                    switch (isOnline)
                    {
                        case true:
                            //try
                            //{
                            ds.Tables[0].Rows[i].SetField("online", true);
                            //windowsUpdateToast.Send_WindwsUpdateToast(computerName); //Sending toast notification if computer is online
                            ds.Tables[0].Rows[i].SetField("status", "Sent");
                            //ds.Tables[0].Rows[i]["status"] = "Sent";
                            //    break;
                            ////}
                            ////catch (Exception psException)
                            ////{
                            //    ds.Tables[0].Rows[i]["online"] = false;
                            //ds.Tables[0].Rows[i].SetField("online", false);
                            //ds.Tables[0].Rows[i].SetField("status", "Failed");
                            //    ds.Tables[0].Rows[i]["status"] = "Failed";
                            //    //break;
                            //}

                            break;
                          
                        case false:

                                ds.Tables[0].Rows[i].SetField("online", false);
                            break;


                    }

                      
                }

            //}
            //catch (Exception dateTimeException)
            //{

            //}

        }


        }



        private void btn_StartStop_Click(object sender, RoutedEventArgs e)
        {

           // ds.WriteXml((@"C:\temp\ToastData.ds"), XmlWriteMode.WriteSchema);
            string btnCurrentText = btn_StartStop.Content.ToString();
            if(btnCurrentText == "Start")
            {
                gridToastItems.IsReadOnly = true;
                btn_Schedule.IsEnabled = false;
                
                StartToastMonitoring(true);
            }
            else if(btnCurrentText == "Stop")
            {
                
                StartToastMonitoring(false);
                gridToastItems.IsReadOnly = false;
                btn_Schedule.IsEnabled = true;
               
            }
          

        }

我遇到的错误如下所示。据我所知,迭代器似乎在行数范围内。

我已经知道是什么导致了问题。如果 ping 功能无法获得 ping 结果并引发 ping 异常,则 ping 计算机的过程会花费大量时间。

必须增加计时器的间隔才能完成所有处理。我会想出另一种方法并尝试并行 ping 计算机。