BackgroundWorker OnWorkCompleted jette cross-thread exception

J'ai un simple contrôle utilisateur pour la base de données de pagination, qui utilise un contrôleur pour effectuer le DAL appels. J'utilise un BackgroundWorker pour effectuer le levage lourd, et sur la OnWorkCompleted cas, je ré-activer les boutons, changer un TextBox.Text propriété et le déclenchement d'un événement pour le formulaire parent.

Forme d'Un détient mon UserControl. Quand j'ai cliquer sur un bouton qui ouvre le formulaire B, même si je ne fais rien "il" et juste à la fermer, et essayer de le faire dans la page suivante à partir de ma base de données, le OnWorkCompleted est appelée sur le thread de travail (et non pas mon thread Principal), et jette un cross-thread exception.

Pour le moment, j'ai ajouté une case pour InvokeRequired au gestionnaire de là, mais ce n'est pas le point de l'ensemble de OnWorkCompleted est d'être appelé sur le thread Principal? Pourquoi ne serait-il pas fonctionner comme prévu?

EDIT:

J'ai réussi à cerner le problème à arcgis et BackgroundWorker. J'ai la solution suivante qui ajoute une Commande à arcmap, qui s'ouvre d'un simple Form1 avec deux boutons.

Le premier bouton exécute une BackgroundWorker qui dort pour 500ms et les mises à jour d'un compteur.
Dans le RunWorkerCompleted méthode il vérifie InvokeRequired, et met à jour le titre pour montrer whethever la méthode a été initialement s'exécute dans le thread principal ou le thread de travail.
Le deuxième bouton ouvre juste Form2, qui ne contient rien.

Au premier abord, tous les appels à RunWorkerCompletedare sont réalisées à l'intérieur du thread principal (Comme prévu - c'est le whold point de la RunWorkerComplete méthode, Au moins par ce que je comprends de la MSDN sur BackgroundWorker)

Après l'ouverture et la fermeture Form2, le RunWorkerCompleted est toujours appelée sur le thread de travail. Je tiens à ajouter que je peux juste laisser cette solution pour le problème tel qu'il est (case pour InvokeRequired dans le RunWorkerCompleted méthode), mais je veux comprendre pourquoi il se passe à l'encontre de mes attentes. Dans mon "vrai" code que j'aimerais toujours savoir que la RunWorkerCompleted méthode est appelée sur le thread principal.

J'ai réussi à cerner le point de le problème à la form.Show(); commande dans mon BackgroundTesterBtn - si j'utilise ShowDialog() au lieu de cela, je n'ai pas de problème (RunWorkerCompleted s'exécute toujours sur le thread principal). J'ai besoin d'utiliser Show() dans mon projet ArcMap, de sorte que l'utilisateur ne sera pas lié à la forme.

J'ai aussi essayé de reproduire le bug sur un projet WinForms. J'ai ajouté un simple projet qui ouvre la première forme sans ArcMap, mais dans ce cas je n'arrivais pas à reproduire le bug - RunWorkerCompleted couru sur le thread principal, que j'ai utilisé Show() ou ShowDialog(), avant et après l'ouverture de Form2. J'ai essayé d'ajouter une troisième forme d'agir en tant que forme principale avant mon Form1, mais il n'a pas changé le résultat.

Ici est mon simple sln (VS2005sp1) - il faut

ESRI.ArcGIS.ADF(9.2.4.1420)

ESRI.ArcGIS.ArcMapUI(9.2.3.1380)

ESRI.ArcGIS.SystemUI (9.2.3.1380)

OriginalL'auteur Noam Gal | 2009-05-04