I have a function which modifies my listview "inputList",the listview has 5 columns. The function is supposed to check the cells in the listview,the cells in the last column will have "NORMAL" with green background if there is nothing wrong and if there is something wrong, it will have "ERROR" with red background in the cell in the last column and also change the color of the cells that are wrong in the same line from the other columns.
There are 4k items, I know that it's pointless to have so many item since the user is not going to read them but I was asked to this way.
I'm using a function with backgroundworker but its not fast enough and thought parallelFor would be faster. But when I try the parallelFor, its freezing the program.
This is the function with backgroundworker which is working but its too slow:
private void bw3_DoWork(object sender, DoWorkEventArgs e)
{
String tempTrain = "";
String tempPredic = "";
String tempNet = "";
Boolean bTrain;
Boolean bPredic;
Boolean bNetErro;
int n;
int nNet = 0;
String tTrain = "";
String tPredic = "";
int nList = 0;
this.Invoke(new MethodInvoker(() => {
nList = inputList.Items.Count;
nNet = menuNetwork.Items.Count;
tTrain = dtrainTextBox.Text;
tPredic = dpredicTextBox.Text;
}));
for (int i = 0; i < nList; i++)
{
ListViewItem.ListViewSubItem temp1 = new ListViewItem.ListViewSubItem();
temp1.BackColor = Color.LightGreen;
temp1.Text = "NORMAL";
this.Invoke(new MethodInvoker(() =>
{
inputList.Items[i].SubItems[0].BackColor = Color.White;
inputList.Items[i].SubItems[1].BackColor = Color.White;
inputList.Items[i].SubItems[2].BackColor = Color.White;
tempTrain = String.Format("{0}\\{1}", tTrain, inputList.Items[i].SubItems[1].Text);
tempPredic = String.Format("{0}\\{1}", tPredic, inputList.Items[i].SubItems[2].Text);
tempNet = (String)inputList.Items[i].SubItems[0].Tag;
}));
bTrain = (!File.Exists(tempTrain));
bPredic = (!File.Exists(tempPredic));
bNetErro = !(int.TryParse(tempNet, out n));
if (!bNetErro)
{
if (!(n < nNet))
{
bNetErro = true;
}
}
this.Invoke(new MethodInvoker(delegate
{
if (bTrain) inputList.Items[i].SubItems[1].BackColor = Color.Red;
if (bPredic) inputList.Items[i].SubItems[2].BackColor = Color.Red;
if (bNetErro) inputList.Items[i].SubItems[0].BackColor = Color.Red;
if (bTrain | bPredic | bNetErro) { temp1.Text = "Erro"; temp1.BackColor = Color.Red; }
try { inputList.Items[i].SubItems[4] = temp1; }
catch (ArgumentOutOfRangeException) { inputList.Items[i].SubItems.Add(temp1); }
}));
}
}
And this is the function with ParallelFor, the program stops working even when I try a very small example with only items.
private void tent1()
{
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 4;
String tempTrain = "";
String tempPredic = "";
String tempNet = "";
String tTrain = dtrainTextBox.Text;
String tPredic = dpredicTextBox.Text;
Boolean bTrain;
Boolean bPredic;
Boolean bNetErro;
int n;
int nNet = networkList.Items.Count;
Parallel.For(0, inputList.Items.Count,
i =>
{
ListViewItem.ListViewSubItem temp1 = new ListViewItem.ListViewSubItem();
temp1.BackColor = Color.LightGreen;
temp1.Text = "NORMAL";
Console.WriteLine(i);
this.Invoke(new MethodInvoker(() =>
{
inputList.Items[i].SubItems[0].BackColor = Color.White;
inputList.Items[i].SubItems[1].BackColor = Color.White;
inputList.Items[i].SubItems[2].BackColor = Color.White;
tempTrain = String.Format("{0}\\{1}", tTrain, inputList.Items[i].SubItems[1].Text);
tempPredic = String.Format("{0}\\{1}", tPredic , inputList.Items[i].SubItems[2].Text);
tempNet = (String)inputList.Items[i].SubItems[0].Tag;
}));
bTrain = (!File.Exists(tempTrain));
bPredic = (!File.Exists(tempPredic));
bNetErro = !(int.TryParse(tempNet, out n));
if (!bNetErro)
{
if (!(n < nNet))
{
bNetErro = true;
}
}
this.Invoke(new MethodInvoker(delegate
{
if (bTrain) inputList.Items[i].SubItems[1].BackColor = Color.Red;
if (bPredic) inputList.Items[i].SubItems[2].BackColor = Color.Red;
if (bNetErro) inputList.Items[i].SubItems[0].BackColor = Color.Red;
if (bTrain | bPredic | bNetErro) { temp1.Text = "Erro"; temp1.BackColor = Color.Red; }
try { inputList.Items[i].SubItems[4] = temp1; }
catch (ArgumentOutOfRangeException) { inputList.Items[i].SubItems.Add(temp1); }
}));
});
}
How can I copy all items of the listview to a List without reference? I think adding/modify directly into the listview and the invokes are slowing the function so creating: List<ListViewItem> tList
I would modify everything in the tList and then I would use inputList.Items.AddRange(tList.ToArray());
This would remove all the invokes inside the loop.
ListViewItem[] tItemsTemp = null;
this.Invoke(new MethodInvoker(() =>
{
tItemsTemp = new ListViewItem[inputList.Items.Count];
inputList.Items.CopyTo(tItemsTemp, 0);
nList = inputList.Items.Count;
nNet = menuNetwork.Items.Count;
tTrain = dtrainTextBox.Text;
tPredic = dpredicTextBox.Text;
}));
List<ListViewItem> tList = new List<ListViewItem>(tItemsTemp);
ListViewItem[] tItems = (ListViewItem[]) tItemsTemp.Clone();
//Modifies the list or array of listviewitems
this.Invoke(new MethodInvoker(delegate
{
inputList.Items.Clear();
// Just one of them,not the 3,just showing how i would call them.
inputList.Items.AddRange(tItems);
inputList.Items.AddRange(tItemsTemp);
inputList.Items.AddRange(tList.ToArray());
}));
But tItemsTemp,tItems,tList were all references... How can I copy with creating a reference?