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

Contribuez .NET Discussion :

[C# .NET 2] FolderBrowserDialog en MultiThread [À publier]


Sujet :

Contribuez .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut [C# .NET 2] FolderBrowserDialog en MultiThread


    Aujourd'hui j'ai eu une jolie petite érreur qui m'a légèrement embétté car je n'ai rien trouvé d'intéréssant sur le net ...

    Scénario :
    Dans la conception de mon logiciel j'ai eu à un moment la possibilité de séparer 2 fenêtres WinForm dans 2 threads différents : le premier thread est celui dans lequel s'exécute la form principale de l'application, et le second est crée avec un BeginInvoke sur une methode anonyme ...
    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
     
    public override void ExecuteWizard()
            {
                MethodInvoker async = new MethodInvoker( delegate
                {
                    try
                    {
                        AsyncExecuteWizard();
                    }
                    catch (Exception ex)
                    {
                        DreamShield.IDE.Elements.Dialogs.ExecutorErrorDialog.RaiseErrorDialog(ex);
                    }
                });
                async.BeginInvoke(null, null);
            }
    Jusque là tout va bien, c'est nikel ce que je voulais, mais dans cette nouvelle fenêtre, crée à partir de AsyncExecuteWizard j'ai voulu afficher un FolderBrowserDialog, et c'est là que j'ai eu ma suprise : il n'y avais dans le FolderBrowserDialog que les bouttons, mais pas le TreeView perméttant d'accéder aux dossiers. Pourtant mon application était bien en STAThread ...

    Astuces
    La seule astuce que j'ai trouvé pour palier à ce problème et d'avoir dans AsyncExecuteWizard une référence à la form principale de l'application. Ensuite à partir de cette form l'on fait un mainForm.Invoke(fonction_appellant_le_FolderBrowserDialog);.
    Seulement, si l'on appelle simplement le Invoke, le thread ( le 2e, pas celui de la form principale ) est bloqué et le paint de la 2e form n'a plus lieu, il faut donc faire encore un BeginInvoke ...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    mainForm.BeginInvoke(new MethodInvoker(delegate
    {
       if(folderBrowserDialog.ShowDialog(_la_2e_form) == DialogResult.OK)
       {
       }
    }));
    et là, le FolderBrowserDialog fonctionne correctement...

    Je ne sais pas si c'est la solution la plus simple, mais n'ayant pas trouvé de réele solution sur le net, j'espère qu'elle pourra un jour aider quelqu'un

    NB: pour ceux qui voudrait savoir ce "bug" est du à COM en STAThread ... le FolderBrowserDialog ne peut pas créer d'instance des interfaces du Shell de Windows sur un autre Thread que le premier ... je n'ai pas voulu éssayer avec MTAThread car toutes les pages que j'ai trouvé sur l'explication de l'utilité de l'attribut du Thread préconisent l'utlisation de STAThread dès que l'on fait du WinForms

    Edit: Même situation avec un OpenFileDialog ...

  2. #2
    Rédacteur
    Avatar de Giovanny Temgoua
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    3 830
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 3 830
    Par défaut
    Ce serait une bonne entrée pour la FAQ je pense

    Je pense qu'un petit zip avec un code test serait

  3. #3
    Rédacteur
    Avatar de dev01
    Profil pro
    Inscrit en
    Mai 2004
    Messages
    2 451
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 451
    Par défaut
    Salut .

    Bon je suis un peu tard mais je pense que cette proposition serait mieux sous forme de source.
    Pour ma part je pense que c'est trop long pour être dans la FAQ

  4. #4
    Rédacteur
    Avatar de Giovanny Temgoua
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2003
    Messages
    3 830
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2003
    Messages : 3 830
    Par défaut
    Citation Envoyé par dev01
    Salut .

    Bon je suis un peu tard mais je pense que cette proposition serait mieux sous forme de source.
    Pour ma part je pense que c'est trop long pour être dans la FAQ
    Heu ... En effet.
    Je pensais à poster l'explication dans la FAQ, poster le source dans les sources et référencer l'entrée dans les sources dans la QR de la FAQ

  5. #5
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    oops, j'avais oublié, je vais faire l'exemple

  6. #6
    Expert confirmé
    Avatar de smyley
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    6 270
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 6 270
    Par défaut
    Voilà ...
    Dans l'exemple j'ai utilisé Thread pour démarrer la 2e fenêtre. Il y a plusieurs petits détails cependant quand à l'utilisation de BeginInvoke :

    si l'on fait un code du genre pour lancer la 2e fenêtre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    this.BeginInvoke(...);
    Il n'y a pas le bug de FolderBrowserDialog, mais en réalité les deux fenêtres ne sont pas séparés comme pour les Thread et donc un blocage dans Form2 bloquerai Form1 par contre
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    MethodInvoker method = new MethodInvoker(...);
    method.BeginInvoke(...);
    La les deux fenêtres sont bien séparés dans deux thread différents et le bug survient ...

    La raison est que la bibliotèque OLE/COM du Shell de Windows ne supporte pas les applications multi-thread. La source de cette information et tout simplement le méssage d'érreur que l'on obtient lors du bug en déboggant avec Visual Studio l'application :
    Le thread actuel doit être en mode STA (Single Thread Apartment) avant que des appels OLE puissent être effectués. Assurez-vous que votre fonction Main est marquée comme STAThreadAttribute. Cette exception n'est déclenchée que si un débogueur est attaché au processus.
    Fichiers attachés Fichiers attachés

Discussions similaires

  1. [.Net 2] Multithreading
    Par Invité dans le forum Windows Forms
    Réponses: 12
    Dernier message: 15/04/2008, 01h06
  2. Réponses: 2
    Dernier message: 11/05/2007, 23h27
  3. [VB.NET 2.0] Serveur en MultiThreading
    Par Aspic dans le forum Windows Forms
    Réponses: 1
    Dernier message: 15/03/2007, 12h46
  4. Réponses: 2
    Dernier message: 24/03/2006, 10h18
  5. [VC6.0][.NET]MultiThread et MultiProcesseur ?
    Par matazz dans le forum MFC
    Réponses: 3
    Dernier message: 19/09/2005, 10h50

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