我的C#应用程序有问题,它可以正常运行或运行x分钟,但在某些时候遇到错误,抱怨“ InvaildOperationException Collection被修改”。我是C#的新手,即使阅读其他文章,也找不到解决方案。
从我看完帖子后可以看出来,这与我的for循环有关,有人可以告诉我我做错了什么。
我认为该错误是由UpdateGraph函数引起的。
该代码旨在连接到Cisco路由器,并通过串行获取蜂窝数据,并以图形和richTextBox形式显示,这些数据都可以正常工作,而减去我在某个时候得到的错误:(
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;
namespace Cisco_Cellular_Diagnostics
{
public partial class Form1 : Form
{
SerialPort serialPort;
string[] ports;
string rawStrings;
int ComPort_ComboBoxIndex;
bool serialIsOpen = false;
bool autoScroll = false;
readonly String executingFolder = System.IO.Path.GetDirectoryName(Application.ExecutablePath);
TextWriter txtFile;
List<int> bandwidthArray = new List<int>();
List<int> rssiArray = new List<int>();
List<int> rsrpArray = new List<int>();
List<int> rsrqArray = new List<int>();
List<int> snrArray = new List<int>();
List<int> nearbyCellsArray = new List<int>();
private static System.Timers.Timer pollingTimer;
public Form1()
{
InitializeComponent();
ports = SerialPort.GetPortNames();
ToolTip toolTip1 = new ToolTip
{
AutoPopDelay = 5000,
InitialDelay = 500,
ReshowDelay = 500,
ShowAlways = true
};
ComPortComboBox.Items.AddRange(ports);
ComPortComboBox.SelectedIndex = 0;
autoScroll = true;
pollingTimer = new System.Timers.Timer(5000);
pollingTimer.Elapsed += new ElapsedEventHandler(SendCellularCmd);
Console.WriteLine("executingFolder = " + executingFolder);
String fileDate = DateTime.Today.ToString("d").Replace("/", "-");
txtFile = new StreamWriter(executingFolder + "\\Cisco Celluar log " + fileDate + ".txt", true);
LoadChart();
}
private void LoadChart()
{
var chart = chart1.ChartAreas[0];
chart.AxisX.IntervalType = DateTimeIntervalType.Number;
chart.AxisX.LabelStyle.Format = "";
chart.AxisY.LabelStyle.Format = "";
chart.AxisX.LabelStyle.IsEndLabelVisible = true;
chart.AxisX.Minimum = 0;
chart.AxisY.Minimum = -128;
chart.AxisY.Maximum = 128;
chart.AxisX.Interval = 1;
chart.AxisY.Interval = 16;
chart1.Series[0].IsVisibleInLegend = false;
chart.AxisX.Title = "Reading";
chart.AxisY.Title = "dB";
//chart1.Series[0].XValueType = ChartValueType.DateTime;
chart1.Series.Add("Bandwidth");
chart1.Series["Bandwidth"].ChartType = SeriesChartType.Line;
chart1.Series["Bandwidth"].Color = Color.Green;
chart1.Series["Bandwidth"].BorderWidth = 8;
chart1.Series.Add("RSSI");
chart1.Series["RSSI"].ChartType = SeriesChartType.Line;
chart1.Series["RSSI"].Color = Color.Blue;
chart1.Series["RSSI"].BorderWidth = 8;
chart1.Series.Add("RSRP");
chart1.Series["RSRP"].ChartType = SeriesChartType.Line;
chart1.Series["RSRP"].Color = Color.Yellow;
chart1.Series["RSRP"].BorderWidth = 8;
chart1.Series.Add("RSRQ");
chart1.Series["RSRQ"].ChartType = SeriesChartType.Line;
chart1.Series["RSRQ"].Color = Color.Red;
chart1.Series["RSRQ"].BorderWidth = 8;
chart1.Series.Add("SNR");
chart1.Series["SNR"].ChartType = SeriesChartType.Line;
chart1.Series["SNR"].Color = Color.Purple;
chart1.Series["SNR"].BorderWidth = 8;
chart1.Series.Add("Nearby cells");
chart1.Series["Nearby cells"].ChartType = SeriesChartType.Line;
chart1.Series["Nearby cells"].Color = Color.DarkGray;
chart1.Series["Nearby cells"].BorderWidth = 8;
chart1.Series["Bandwidth"].Points.AddXY(0, 0);
chart1.Series["RSSI"].Points.AddXY(0, 0);
chart1.Series["RSRP"].Points.AddXY(0, 0);
chart1.Series["RSRQ"].Points.AddXY(0, 0);
chart1.Series["SNR"].Points.AddXY(0, 0);
chart1.Series["Nearby cells"].Points.AddXY(0, 0);
}
private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
BeginInvoke((MethodInvoker)delegate ()
{
rawStrings += indata;
//txtFile.Write(indata);
//txtFile.WriteLine(DateTime.Now + "\n");
ReceivedDataRichTextBox.AppendText(indata);
if (autoScroll)
ReceivedDataRichTextBox.ScrollToCaret();
});
}
private void OpenSerial_Click(object sender, EventArgs e)
{
ComPort_ComboBoxIndex = ComPortComboBox.SelectedIndex;
if (ComPort_ComboBoxIndex >= 0 && !serialIsOpen)
{
try
{
string selectedCOM = ComPortComboBox.SelectedItem.ToString();
serialPort = new SerialPort(selectedCOM, 9600);
serialPort.ReadTimeout = 3000;
serialPort.Parity = Parity.None;
serialPort.StopBits = StopBits.One;
serialPort.DataBits = 8;
serialPort.Handshake = Handshake.None;
serialIsOpen = true;
serialPort.DataReceived += new SerialDataReceivedEventHandler(SerialPort_DataReceived);
OpenSerialOne.Text = "Close Serial";
serialPort.Open();
LogIntoCLI();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
else if (serialIsOpen)
{
try
{
serialPort.Write("exit");
serialPort.Close();
txtFile.Close();
pollingTimer.Enabled = false;
serialIsOpen = false;
OpenSerialOne.Text = "Open Serial";
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
else
{
MessageBox.Show("Error, check the baud Rate and COM port is selected and try again.");
}
}
private void LogIntoCLI()
{
if (serialIsOpen)
{
try
{
serialPort.Write("\r");
Thread.Sleep(2000);
serialPort.Write("\r"); // "exit\r"
Thread.Sleep(2000);
serialPort.Write("enable\r");
Thread.Sleep(3000);
serialPort.Write("met0cean\r");
Thread.Sleep(2000);
pollingTimer.Enabled = true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
private void SendCellularCmd(object sender, ElapsedEventArgs e)
{
ExtractData();
serialPort.Write("show cell 0 radio\r");
Console.WriteLine("sending command...");
}
private void ExtractData()
{
try
{
txtFile.Write(rawStrings);
txtFile.WriteLine(DateTime.Now + "\n");
String[] listOfStrings = rawStrings.Split('\n');
rawStrings = "";
foreach (String value in listOfStrings)
{
String[] strlist = value.Split(' ');
if (value.IndexOf("Bandwidth") >= 0 && strlist.Length == 5)
{
if (int.TryParse(strlist[3], out int extractedValue))
UpdateGraph(extractedValue, "Bandwidth", ref bandwidthArray);
}
else if (value.IndexOf("RSSI") >= 0 && strlist.Length == 5)
{
if (int.TryParse(strlist[3], out int extractedValue))
UpdateGraph(extractedValue, "RSSI", ref rssiArray);
}
else if (value.IndexOf("RSRP") >= 0 && strlist.Length == 5)
{
if (int.TryParse(strlist[3], out int extractedValue))
UpdateGraph(extractedValue, "RSRP", ref rsrpArray);
}
else if (value.IndexOf("RSRQ") >= 0 && strlist.Length == 5)
{
if (int.TryParse(strlist[3], out int extractedValue))
UpdateGraph(extractedValue, "RSRQ", ref rsrqArray);
}
else if (value.IndexOf("SNR") >= 0 && strlist.Length == 5)
{
if (int.TryParse(strlist[3], out int extractedValue))
UpdateGraph(extractedValue, "SNR", ref snrArray);
}
else if (value.IndexOf("nearby cells") >= 0 && strlist.Length == 6)
{
if (int.TryParse(strlist[5], out int extractedValue))
UpdateGraph(extractedValue, "Nearby cells", ref nearbyCellsArray);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
private void UpdateGraph(int a_value, String a_ID, ref List<int> a_List)
{
try
{
// keep the list count to 20 items
if (a_List.Count == 20)
a_List.RemoveAt(0);
a_List.Add(a_value);
// clear chart and add items
chart1.Series[a_ID].Points.Clear();
for (int i = 0; i < a_List.Count; i++)
{
chart1.Series[a_ID].Points.AddXY(i, a_List[i]);
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
if (e.CloseReason == CloseReason.WindowsShutDown) return;
// Confirm user wants to close
switch (MessageBox.Show(this, "Are you sure you want to close?", "Closing Application", MessageBoxButtons.YesNo))
{
case DialogResult.No:
e.Cancel = true;
break;
default:
try
{
txtFile.Close();
serialPort.Write("exit");
serialPort.Close();
pollingTimer.Enabled = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
break;
}
}
private void PollingTimeNumericUpDown_ValueChanged(object sender, EventArgs e)
{
pollingTimer.Interval = Convert.ToDouble(PollingTimeNumericUpDown.Value);
}
private void ClearDataButton_Click(object sender, EventArgs e)
{
ReceivedDataRichTextBox.Clear();
chart1.Series["Bandwidth"].Points.Clear();
chart1.Series["RSSI"].Points.Clear();
chart1.Series["RSRP"].Points.Clear();
chart1.Series["RSRQ"].Points.Clear();
chart1.Series["SNR"].Points.Clear();
chart1.Series["Nearby cells"].Points.Clear();
chart1.Series["Bandwidth"].Points.AddXY(0, 0);
chart1.Series["RSSI"].Points.AddXY(0, 0);
chart1.Series["RSRP"].Points.AddXY(0, 0);
chart1.Series["RSRQ"].Points.AddXY(0, 0);
chart1.Series["SNR"].Points.AddXY(0, 0);
chart1.Series["Nearby cells"].Points.AddXY(0, 0);
}
private void SendManualCmd_Click(object sender, EventArgs e)
{
try
{
serialPort.Write(textBox1.Text + "\r");
textBox1.Clear();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
private void ReloadComPortsButton_Click(object sender, EventArgs e)
{
ComPortComboBox.Items.Clear();
ports = SerialPort.GetPortNames();
ComPortComboBox.Items.AddRange(ports);
}
private void ComComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// CiscoComPort = ComPortComboBox.SelectedItem.ToString();
}
}
}