IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

parrallel.foreach avec datagridview [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut parrallel.foreach avec datagridview
    Bonsoir à tous,

    J'ai dans une interface winform un datagridview. Lorsque je clique sur un bouton, je voudrais vérifier les éléments sélectionnés Mon code est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
     
    private List<Mark> Test = new List<Mark>();
     
    private void button2_Click(object sender, EventArgs e)
    		{
    			List<Mark> lst = new List<Mark>();
    			Mark m = new Mark();
    			foreach (DataGridViewRow row in dataGridView1.SelectedRows)
    			{
    				m = row.DataBoundItem as Mark;			
    				lst.Add(m);
    			}
     
     
    			Parallel.ForEach(lst, new ParallelOptions { MaxDegreeOfParallelism = 4 }, cm => 
    			                 {
    			                 	cm.Titre = MarkNet.Tools.HtmlTools.gettitle(m.Href);
    			                 	if (cm.Titre != "")
    			                 	{
    			                 		lock (Test)
    			                 		{
    			                 			Mark obj = Test.FirstOrDefault( x=> x.UId == m.UId);
    			                 			if (obj != null) obj.Titre = m.Titre;
    			                 			dataGridView1.Update();
    			                 		}
    			                 	}
    			                 }
    			                );
    }
    Pourtant le seul message que j'obtient à l’exécution est : Une ou plusieurs erreurs se sont produites.
    Rien dans le compilateur ni dans le déboguage.

    Pourriez-vous m'éclairer? Merci

  2. #2
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Le problème vient très certainement du fait que seul le thread graphique est autorisé à accéder aux éléments graphiques (par exemple, en faisant dataGridView1.Update();).

    Maintenant, Parallel.ForEach utilises plusieurs thread. Dans ton code, jusqu'à 4. Et le code dans la boucle accède à des éléments graphiques. Résultat : InvalidOperationException.

    Solutions :
    • ou bien enlever le Parallel.ForEach et le remplacer par une boucle for classique ;
    • ou bien enlever tous les accès aux éléments graphiques de la boucle.


    Au passage, l'usage de l'instruction lock est généralement à éviter au sein du thread graphique.

  3. #3
    Membre chevronné
    Avatar de nouanda
    Homme Profil pro
    Hobbyist
    Inscrit en
    Mai 2002
    Messages
    246
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Australie

    Informations professionnelles :
    Activité : Hobbyist

    Informations forums :
    Inscription : Mai 2002
    Messages : 246
    Par défaut
    Il est possible pour un thread d'accéder aux éléments graphiques de l'UI (même si c'est déconseillé...). Il faut pour cela créer une méthode dédiée, et un callback.

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
            private void UpdateDgv()
            {
                if (this.dataGridView1.InvokeRequired)
                {
                    UpdateDgvCallback d = new UpdateDgvCallback(UpdateDgv);
                    this.Invoke(d, new object[] { });
                }
                else
                {
                    this.dataGridView1.Update();
                }
            }
    Déclarer le callback ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    delegate void UpdateDgvCallback();
    Tu peux ainsi, dans tes thread, remplacer dataGridView1.Update(); par UpdateDgv();

    Edit: regarde ici http://stackoverflow.com/questions/6...er-thread-in-c pour des méthodes plus générales

  4. #4
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Citation Envoyé par nouanda Voir le message
    Il est possible pour un thread d'accéder aux éléments graphiques de l'UI (même si c'est déconseillé...). Il faut pour cela créer une méthode dédiée, et un callback.
    Ce n'est pas du tout déconseillé. C'est la méthode à suivre dès lors qu'un thread autre que le thread graphique souhaite mettre à jour l'UI.

    Par contre, vu l'utilisation de lock dans son code, je déconseillerai fortement cette approche, vu les risques d'obtenir des interblocages.

  5. #5
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut
    Bon ok je ne m'en sort pas. Donc je vais poser la question autrement.

    J'ai les procédures suivantes qui fonctionne parfaitement.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    private List<Mark> lstMark = new List<Mark>();
     
    private void button2_Click(object sender, EventArgs e)
    {
    	Mark m = new Mark();
    	foreach (DataGridViewRow row in dataGridView1.SelectedRows)
    	{
    		m = row.DataBoundItem as Mark;			
    		m.Titre = MarkNet.Tools.HtmlTools.gettitle(m.Href);
    		if(m.Titre != "")
                    {
                    	Mark obj = Test.FirstOrDefault( x=> x.UId == m.UId);
    			if (obj != null) obj.Titre = m.Titre;
    			dataGridView1.Update();
                    }
    	}
    }
    Comment puis-je convertir cette procédure afin de faire la boucle sur plusieurs ligne en même temps?

    Merci pour votre aide.

  6. #6
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    comment est définie la variable ou propriété Test ?

  7. #7
    Membre Expert
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2013
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Industrie

    Informations forums :
    Inscription : Octobre 2013
    Messages : 1 563
    Par défaut
    Citation Envoyé par nouanda Voir le message
    Il est possible pour un thread d'accéder aux éléments graphiques de l'UI (même si c'est déconseillé...). Il faut pour cela créer une méthode dédiée, et un callback.

    Pour compléter ce qu'a dit @François DORIN, le this.Invoke(CallBack) est réalisé sur le thread principale de "this" et donc, le cas échéant, le thread principale de l'application (qui gère l'UI). Donc tu n'accèdes pas réellement aux composants graphiques dans un autres thread, mais bien dans celui qui gère ton UI.

  8. #8
    Membre confirmé
    Profil pro
    Débutant
    Inscrit en
    Février 2007
    Messages
    134
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : Belgique

    Informations professionnelles :
    Activité : Débutant
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Février 2007
    Messages : 134
    Par défaut
    Merci ça fonctionne parfaitement

    juste une coquille
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    UpdateDgvCallback d = new UpdateDgvCallback(UpdateDgv); à remplacer par UpdateDgvCallback d = new UpdateDgvCallback(UpdateMark);
    Je mets en résolus et merci du coup de main

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 5
    Dernier message: 29/03/2007, 00h08
  2. Foreach avec <tr>
    Par chipie189 dans le forum Langage
    Réponses: 2
    Dernier message: 16/01/2007, 01h44
  3. [c#] Travail avec datagridview.
    Par penchu dans le forum Windows Forms
    Réponses: 5
    Dernier message: 21/12/2006, 17h59
  4. Utilisation de foreach avec les sessions sous PHP5
    Par frochard dans le forum Langage
    Réponses: 1
    Dernier message: 11/11/2006, 01h14
  5. [Tableaux] Problème de foreach avec des checkboxes
    Par nanor21 dans le forum Langage
    Réponses: 10
    Dernier message: 15/05/2006, 01h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo