我正在尝试更改后台工作程序中的列表视图。
private void bw2_DoWork(object sender, DoWorkEventArgs e)
{
String temp = "aaaa";
int n;
int nNet;
String[] ar = (String[])e.Argument;
int nList = int.Parse(ar[3]);
String tTrain = ar[0];
String tPredic = ar[1];
this.BeginInvoke(new MethodInvoker(() => { nList = inputList.Items.Count; }));
for (int i = 0; i < nList; i++)
{
Console.WriteLine(i);
ListViewItem.ListViewSubItem temp1 = new ListViewItem.ListViewSubItem();
temp1.BackColor = Color.Green;
temp1.Text = "NORMAL";
this.BeginInvoke( new MethodInvoker( () => { temp = String.Format("{0}\\{1}", dtrainTextBox.Text , inputList.Items[i].SubItems[1].Text); }));
// temp = String.Format("{0}\\{1}", tTrain, inputList.Items[i].SubItems[1].Text);
if (!File.Exists(temp))
{
this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[1].BackColor = Color.Red; }));
// inputList.Items[i].SubItems[1].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
this.BeginInvoke(new MethodInvoker(() => { temp = String.Format("{0}\\{1}", dpredicTextBox.Text, inputList.Items[i].SubItems[1].Text); }));
// temp = String.Format("{0}\\{1}", tPredic, inputList.Items[i].SubItems[2].Text);
if (!File.Exists(temp))
{
this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[2].BackColor = Color.Red; }));
// inputList.Items[i].SubItems[2].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
Console.WriteLine(String.Format("i:{0} nList:{1}",i,nList));
this.BeginInvoke(new MethodInvoker(() => { temp = inputList.Items[i].SubItems[0].Text; }));
//temp = inputList.Items[i].SubItems[0].Text
Console.WriteLine(temp);
if (int.TryParse(temp, out n) & int.TryParse(ar[2], out nNet))
{
if (n > nNet)
{
this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[0].BackColor = Color.Red; }));
// inputList.Items[i].SubItems[0].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
}
else
{
this.BeginInvoke(new MethodInvoker(delegate { inputList.Items[i].SubItems[0].BackColor = Color.Red; }));
// inputList.Items[i].SubItems[0].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
this.BeginInvoke(new MethodInvoker(delegate{inputList.Items[i].SubItems.Add(temp1);}));
}
}
问题在于nList
我正在测试nList = 2060
并且我在其中一个inputList.Items[i]
中收到错误:
类型'System.ArgumentOutOfRangeException'的未处理异常 发生在System.Windows.Forms.dll其他信息: InvalidArgument ='2060'的值对'index'无效。
我不知道这是怎么回事,“i”的最后一个值应该是2059,它是如何尝试访问这个索引2060的。 nList有inputList.Items.Count值,我把它作为参数传递给我,因此我不需要使用invoke来获取它的数量。
我刚试过这个:
private void loadButton_Click(object sender, EventArgs e)
{
object[] ar = { dpredicTextBox.Text, dpredicTextBox.Text, nNet.Items.Count, inputList};
bw3.RunWorkerAsync(ar);
}
private void bw3_DoWork(object sender, DoWorkEventArgs e)
{
String temp = "aaaa";
int n;
object[] ar = (Object[])e.Argument;
ListView nList = (ListView) ar[3];
int nNet = (int)ar[2];
String tTrain = (String) ar[0];
String tPredic = (String) ar[1];
foreach(ListViewItem item in nList.Items)
{
ListViewItem.ListViewSubItem temp1 = new ListViewItem.ListViewSubItem();
temp1.BackColor = Color.Green;
temp1.Text = "NORMAL";
temp = String.Format("{0}\\{1}", tTrain, item.SubItems[1].Text);
if (!File.Exists(temp))
{
item.SubItems[1].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
temp = String.Format("{0}\\{1}", tPredic, item.SubItems[2].Text);
if (!File.Exists(temp))
{
item.SubItems[2].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
temp = item.SubItems[0].Text;
if (int.TryParse(temp, out n))
{
if (n > nNet)
{
item.SubItems[0].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
}
else
{
item.SubItems[0].BackColor = Color.Red;
temp1.BackColor = Color.Red;
temp1.Text = "ERRO";
}
item.SubItems.Add(temp1);
this.BeginInvoke(new MethodInvoker(delegate { inputList = nList; }));
}
// this.BeginInvoke(new MethodInvoker(delegate { inputList = nList; }));
}
但它也不起作用:
System.Windows.Forms.dll中发生了'System.InvalidOperationException'类型的异常,但未在用户代码中处理
附加信息:跨线程操作无效:控制'inputList'从其创建的线程以外的线程访问。
答案 0 :(得分:0)
使用BeginInvoke
而不是异步的Invoke
。实际上,计数器i
在循环结束时变为2060,这可能发生在inputList.Items[i]
在一个异步调用中被引用之前。在WinForms控件上调用Invoke
方法会等待调用完成并使循环按预期运行。您的第二个代码示例不起作用,因为无法从后台线程“触摸”WinForms控件。它们只能从主(或GUI)线程访问。