[C# .NET 2] FolderBrowserDialog en MultiThread
:salut:
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 :aie: :
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:
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:
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 :aie:
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 ...
OpenFileDialog en multi-thread
Merci beaucoup les gars, votre discussion m'a permis de ne pas perdre plus de temps...
Mais je ne comprends pas pourquoi cela ne fonctionne pas avec un simple [MTAThread]...8O
Je m'explique :
J'ai réalisé un projet avec VS.net 2003 avec des formulaire où j'ai utilisé le multiple Thread (Jusque là c'est pas sorcier, tout fonctionnait nickel...), mais récemment j'ai fait évoluer le projet en VS.net 2008 et là bug sur bug :bug: :aie:.
C'est normal puisque ils utilisent des versions du framework différents mais c'est là que que le déboggeur m'affichait une erreur me demandant de mettre STA pour le main() (quand j'appelait simplement un OpenFileDialog) , ce que j'ai fait mais par la suite j'avais d'autres problèmes au niveau de la mémoire(beaucoup de traitement lourds pour certains ...
Moralité après quelques recherches sur internet je suis tombé ici et j'ai essayé et cela fonctionnait... si quelqu'un peux m'expliquer pourquoi cela fonctionne sous VS 2003 mais pas sur VS 2008? merci par avance...