2 votes

Mise à jour de plusieurs barres de progression dans 2 boucles différentes

J'ai un programme Windows qui effectue des mises à jour dans une base de données. Il y a deux boucles pour lesquelles j'aimerais afficher la progression. La première boucle obtient une liste de clients et la seconde une liste de sites pour ce client :

DataTable dtCustomers = GetAllCustomers();

foreach(DataRow customer in dtCustomers.Rows)
{
    //update Customer Progressbar...

    //do some updating here...

    DataTable dtLocations = GetAllLocations(customer);

    foreach(DataRow location in dtLocations.Rows)
    {
        //do some updating here...

        //update Location Progressbar...
    }

    //reset Location Progressbar...
}

Ce que j'aimerais faire, c'est montrer une barre de progression visuelle (pb) de chaque boucle. La barre de progression du client s'incrémenterait avec chaque client traité, tout comme la barre de progression de l'emplacement... la seule différence est que la barre de progression de l'emplacement se réinitialiserait après chaque emplacement, car la mise à jour pourrait prendre plus ou moins de temps en fonction de l'emplacement.

J'ai commencé avec un travailleur de fond et j'ai pu mettre à jour la base de données clients sans problème. J'ai mis le code suivant dans un bouton "start" :

private void buttonStart_Click(object sender, EventArgs e)
{
    workerCustomers.RunWorkerAsync();
}

et dans l'événement DoWork() du workerCustomer, je mets les 2 boucles. Je sais que le pb d'emplacement ne sera pas mis à jour parce que cela donnerait l'erreur "Cross thread reference". Alors comment puis-je faire ce que je veux ? J'ai même essayé de mettre 2 bg workers sur le formulaire et d'en appeler un à partir de l'autre, mais là encore, une autre erreur indiquant que le premier worker est occupé.

4voto

Sergey Berezovskiy Points 102044

Lorsque vous rapportez le progrès, vous pouvez passer un objet userState supplémentaire comme deuxième paramètre (voir ReportProgress définition de la méthode) :

workerCustomers.ReportProgress(percentage1, percentage2);

Et dans ProgressChanged vous pouvez mettre à jour les deux barres de progression :

void workerCustomers_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    progressBar1.Value = e.ProgressPercentage; // Customers
    progressBar2.Value = (int)e.UserState; // Locations
}

UPDATE : Comment l'utiliser dans votre cas

DataTable dtCustomers = GetAllCustomers();
int customerIndex = 0;

foreach(DataRow customer in dtCustomers.Rows)
{
    //do some updating here...
    int customerPercentage = ++customerIndex * 100 / dtCustomers.Rows.Count;
    workerCustomers.ReportProgress(customerPercentage, 0);

    int locationIndex = 0;
    DataTable dtLocations = GetAllLocations(customer);

    foreach(DataRow location in dtLocations.Rows)
    {
        //do some updating here...
        int locationPecentage = ++locationIndex * 100 / dtLocations.Rows.Count;
        workerCustomers.ReportProgress(customerPercentage, locationPecentage);
    }

    workerCustomers.ReportProgress(customerPercentage, 0);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X