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 :

Problème avec le multi-threading


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 25
    Par défaut Problème avec le multi-threading
    Bonjour à tous,

    j'ai eu quelques problèmes récemment avec le multi-threading et j'ai réussi jusqu'à présent en utilisant d'autres types, en faisant un peu de bricolage. Mais là je suis face à une erreur que je ne comprends pas.

    Dans la boucle ci-dessous qui s'exécute parallèlement grâce à Parallel.ForEach, qui énumère tous les éléments de la liste list qui contient des Model3D, je crée deux objets qui sont des parties spéciales de currentChildModel3D, la variable locale du foreach en gros.
    Et j'ai l'erreur comme quoi le thread n'a pas accès à l'objet car il n'en ai pas propriétaire, alors que je viens de le créer en local dans la boucle ! Pourtant il me semble bien que mon instanciation d'objet ne correspond pas à une référence mais bien à un type valeur... Je vous laisse juger:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Parallel.ForEach(listChildModel3D, currentChildModel3D =>
                    {
                        GeometryModel3D gm1 = new GeometryModel3D();
                        gm1 = (GeometryModel3D)currentChildModel3D;
    
                        MeshGeometry3D mesh1 = new MeshGeometry3D(); 
                        mesh1 = gm1.Geometry as MeshGeometry3D;//Le thread appelant ne peut pas accéder à l'objet car il n'en ai pas propriétaire
                        
    Geometry g2 = Create2DGeometryFromModel3D(currentChildModel3D, matrixList[listChildModel3D.IndexOf(currentChildModel3D)],gm1,mesh1 );
                        g1.Children.Add(g2); //Ajout à la variable globale, un GeometryGroup
    
                    });
    Je ne vois vraiment pas d'où provient l'erreur étant donné que la variable mesh1 est locale !

    Si quelqu'un avait une idée ce serait super !

    Merci d'avance

  2. #2
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Citation Envoyé par mikeycast Voir le message
    Bonjour à tous,

    j'ai eu quelques problèmes récemment avec le multi-threading et j'ai réussi jusqu'à présent en utilisant d'autres types, en faisant un peu de bricolage. Mais là je suis face à une erreur que je ne comprends pas.

    Dans la boucle ci-dessous qui s'exécute parallèlement grâce à Parallel.ForEach, qui énumère tous les éléments de la liste list qui contient des Model3D, je crée deux objets qui sont des parties spéciales de currentChildModel3D, la variable locale du foreach en gros.
    Et j'ai l'erreur comme quoi le thread n'a pas accès à l'objet car il n'en ai pas propriétaire, alors que je viens de le créer en local dans la boucle ! Pourtant il me semble bien que mon instanciation d'objet ne correspond pas à une référence mais bien à un type valeur... Je vous laisse juger:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Parallel.ForEach(listChildModel3D, currentChildModel3D =>
                    {
                        GeometryModel3D gm1 = new GeometryModel3D();
                        gm1 = (GeometryModel3D)currentChildModel3D;
    
                        MeshGeometry3D mesh1 = new MeshGeometry3D(); 
                        mesh1 = gm1.Geometry as MeshGeometry3D;//Le thread appelant ne peut pas accéder à l'objet car il n'en ai pas propriétaire
                        
    Geometry g2 = Create2DGeometryFromModel3D(currentChildModel3D, matrixList[listChildModel3D.IndexOf(currentChildModel3D)],gm1,mesh1 );
                        g1.Children.Add(g2); //Ajout à la variable globale, un GeometryGroup
    
                    });
    Je ne vois vraiment pas d'où provient l'erreur étant donné que la variable mesh1 est locale !

    Si quelqu'un avait une idée ce serait super !

    Merci d'avance
    A mon humble avis c'est plutôt gm1 qui pose problème!
    D'ailleurs tu créés un GeometryModel3D pour rien...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    GeometryModel3D gm1 = new GeometryModel3D();
    gm1 = (GeometryModel3D)currentChildModel3D;
    se remplace par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GeometryModel3D gm1 = (GeometryModel3D)currentChildModel3D;
    Edit: Euh mais je viens de remarquer que tu fais tout à l'envers en fait
    C'est pareil pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    MeshGeometry3D mesh1 = new MeshGeometry3D(); 
    mesh1 = gm1.Geometry as MeshGeometry3D;
    A quoi ca te sert de créer un MeshGeometry3D si c'est pour l'écraser tout de suite après?

  3. #3
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Bon j'ai feuilleté MSDN un peu plus et j'ai quelques mauvaises nouvelles.
    Tout ce que tu manipules sont des instances de classes (et sont donc par conséquence des types références). De plus GeometryModel3D est un DispatcherObject ce qui signifie que seul le thread qui l'a créée peut y accéder (via la propriété Dispatcher de cet objet). Par conséquent, si il est créée sur le thread de l'UI tu ne peux pas le manipuler dans un autre et si tu le créée dans un autre tu ne peux pas le manipuler avec le thread de l'UI.

    Note: c'était couru d'avance que c'était des types références, car le cast ne sert à rien sur des types valeurs étant donné qu'il n'y a pas d'héritage dans les types valeurs.

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 25
    Par défaut
    Salut,

    Merci beaucoup pour ta réponse. En fait si je m'étais un peu compliqué la vie en écrivant le code en deux lignes au lieu d'une c'est parce que je voulais forcer la création d'une nouvelle instance (avec le new). Mais comme tu le dis c'est dommage c'est forcément une référence...

    Est-ce que tu aurais une idée qui permettrait de passer outre cette difficulté? J'ai bien pensé au mot lock mais évidemment ca ne fonctionne quand même pas étant donné que c'est un DispatcherObject...

    Est-ce que tu saurais manipuler ce type d'objets 3D pour pouvoir l'extraire dans des types valeurs ou thread-safe (tableaux?) afin que je puisse créer autant de gm1 et de mesh qu'il y a de threads? (variables locales)

  5. #5
    Rédacteur
    Avatar de Nathanael Marchand
    Homme Profil pro
    Expert .Net So@t
    Inscrit en
    Octobre 2008
    Messages
    3 615
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Expert .Net So@t
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2008
    Messages : 3 615
    Par défaut
    Citation Envoyé par mikeycast Voir le message
    Salut,

    Merci beaucoup pour ta réponse. En fait si je m'étais un peu compliqué la vie en écrivant le code en deux lignes au lieu d'une c'est parce que je voulais forcer la création d'une nouvelle instance (avec le new). Mais comme tu le dis c'est dommage c'est forcément une référence...

    Est-ce que tu aurais une idée qui permettrait de passer outre cette difficulté? J'ai bien pensé au mot lock mais évidemment ca ne fonctionne quand même pas étant donné que c'est un DispatcherObject...

    Est-ce que tu saurais manipuler ce type d'objets 3D pour pouvoir l'extraire dans des types valeurs ou thread-safe (tableaux?) afin que je puisse créer autant de gm1 et de mesh qu'il y a de threads? (variables locales)
    Non c'est impossible, ce type d'objet doit uniquement être manipulé sur le thread de l'UI. Que cherches tu as faire ?

  6. #6
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Août 2012
    Messages
    25
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Août 2012
    Messages : 25
    Par défaut
    En fait la fonction a pour but de calculer le contour d'objets 3D. A partir de l'objet 3D on calcule sa projection et on en prend le contour.

    Je n'ai pas écrit ce code, je ne peux malheureusement pas expliquer pourquoi telle ou telle solution a été choisie mais juste ce que j'en ai compris.

    Le modèle 3D complet contient tous les objets, mais les calculs se font séparément. (Dans mon bout de code chaque currentChildModel3D est un objet). J'avais au début choisi de paralléliser le calcul des contours, mais j'ai trouvé cela plus judicieux de paralléliser le calcul de chaque objet. C'est-à-dire qu'un thread calcule le contour d'un objet, et pas une partie du contour d'un objet pour tous les objets.

    Seulement voilà, le modèle 3D même enfant ne semble pas pouvoir être utilisé séparément par plusieurs threads.

    En gros c'est toujours la même fonction "Create2DGeometryFromModel3D" qui est appelée, et qui fait le tri entre un modèle ou une famille de modèles (lorsque c'est une famille, elle s'appelle de manière récursive pour chaque modèle, c'est la partie que je souhaite paralléliser).

    J'espère avoir été assez clair dans mes explications, je pourrais te donner plus de détails mais je ne sais pas si c'est utile.

    Merci beaucoup !

Discussions similaires

  1. Problème avec les multi-threads
    Par Dominique49 dans le forum Général Java
    Réponses: 5
    Dernier message: 12/12/2011, 15h20
  2. [SFML] Problème avec affichage en thread
    Par black is beautiful dans le forum SFML
    Réponses: 0
    Dernier message: 05/05/2009, 10h33
  3. Problème avec repaint() et Thread.sleep
    Par fab13 dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 12/08/2008, 23h02
  4. Problème avec TList et Threads
    Par necralbert dans le forum Composants VCL
    Réponses: 6
    Dernier message: 23/08/2007, 14h12
  5. Problème avec la multi-sélection dans une zone de liste
    Par Mimisio dans le forum VBA Access
    Réponses: 2
    Dernier message: 16/07/2007, 16h23

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