C # Progress Bar, Thread, Nested Foreachs

1

Good morning ...

I have the following situation:

I have two lists, the first of about 9000 objects, and the second of 44000 (this can vary from one execution to the next).

Now, I have to find each item in list A in list B, set a couple of attributes and then continue working with those in list A modified.

For this, I have two foreach nests in a new Thread and I intend to fill a ProgressBar while the process lasts (this is new for me in C #)

The problem is that while the process is being done, I get an exception of the type:

  

System.Reflection.TargetInvocationException

Here the code:

private void btn_readTXT_Click(object sender, EventArgs e)
    {
        OpenFileDialog file = new OpenFileDialog();

        if (file.ShowDialog() == System.Windows.Forms.DialogResult.OK)
        {
            Thread backgroundThread = new Thread( 
            new ThreadStart(() =>
            {
                string url = file.FileName;
                IBs = otequiste.ReadFile(url); //Lleno la lista desde el txt

                foreach (cliente cliente in Clientes)
                {
                    foreach (tequiste ib in IBs)
                    {
                        if (cliente.Cli_CUIT == ib.Cuit) 
                        {
                            cliente.Actividad = ib.Cod_act;
                            cliente.Riesgo = ib.Riesgo;
                            cliente.Tipo = ib.Tipo;

                            progressBar1.BeginInvoke(
                            new Action(() =>
                            {
                                progressBar1.Value += 1;
                            }
                        ));
                            break;
                        }
                    }
                }

                MessageBox.Show("Ready", "Ready ? ");


            }));
            backgroundThread.Start();
        }           
    }

My doubts are the following:

a) What does this exception mean? (I do not know when it happens, the bar fills up after about 5 sec, the visual editor leaves it in the Program.cs file in a line that says:

Application.Run(new Form1());

b) Bearing in mind that the number of objects in the lists varies from one execution to the next. How can I effectively fill the progress bar?

(that is, calculate 100% and know how to increase the Value so that it does not go out of range or falls short)

    
asked by FederHico 15.06.2017 в 20:45
source

1 answer

1

Given the conversation we had in the chat , we identified two problems, one was the > performance since having a foreach nested you are practically doing a cross product, and the second one was the value of progressBar1 , it was out of the allowed range.

The solution to the performance section consists in looking for the cliente.Cli_CUIT value through Linq:

foreach (cliente cliente in Clientes)
{
    var ib = (from p in IBs
            where p.Cuit == cliente.Cli_CUIT
            select p).FirstOrDefault();

    if(ib != null) {
        cliente.Actividad = ib.Cod_act;
        cliente.Riesgo = ib.Riesgo;
        cliente.Tipo = ib.Tipo;

        progressBar1.BeginInvoke(
        new Action(() =>
        {
            //progressBar1.Value += 1;
        }
    }
}

The line progressBar1.Value += 1; left commented, this because the code has changed with the changes you made and with which you are already working correctly. The problem was that the maximum value allowed for a ProgressBar is 100, so when increasing it by 1 with each iteration there was a moment that went out of that range, the solution consisted in dividing the number of records processed at the time of each iteration of customers among the total number of clients.

    
answered by 15.06.2017 / 23:04
source