8
votes

Exception à fil croisée lors du réglage WinForms.Form Propriétaire - Comment faire?

J'ai un fil d'interface utilisateur principal qui exécute l'application et crée la fenêtre principale de la fenêtre (appelons-le w code>). J'ai aussi un fil secondaire que je fais tourner et qui crée une boîte de dialogue (appelons-le b code>).

Je souhaite définir le propriétaire de la boîte de dialogue B code> Pour être la fenêtre principale w code>. Le réglage de la propriétaire B code> se produit sur le thread qui a créé B code>. Fondamentalement: p>

System.InvalidOperationException was unhandled by user code
  Message=Cross-thread operation not valid: Control 'B' accessed from a
  thread other than the thread it was created on.
  Source=System.Windows.Forms


4 commentaires

N'utilisez pas de formulaires sur plusieurs threads. Cela vous donnera plus de problèmes que ça ne va pas.


Avez-vous lu ceci alors post: Stackoverflow.com/Questtions/3046245/... ? Si cela ne vous aide pas, vous devez publier le code qui vous donne l'erreur.


Peut-être que vous pouvez nous dire quels caractéristiques de possession que vous espériez profiter (espérons-le pas tous), et nous pourrions suggérer des moyens d'obtenir des effets similaires?


Merci à tous ceux qui ont posté; Je sais que je demande des ennuis. Je dois exécuter un code hérité sur le fil principal de l'interface utilisateur, et je souhaite avoir une boîte de dialogue de progression indiquant que cela se produit; Et je ne peux pas laisser le fil de l'interface utilisateur principal de la boîte de dialogue de progrès. Je suis donc allé pour un dialogue de progression géré 100% par un autre fil.


3 Réponses :


3
votes

B doit être créé sur le thread de l'interface utilisateur.

Vous pouvez toujours interagir avec B à partir du thread secondaire en utilisant contrôler.invoke . .


1 commentaires

Dans mon cas, cela ne fonctionnera pas pour ce que j'ai l'intention de faire: ma fenêtre B ne mettra pas à jour si le fil d'interface utilisateur principal est bloqué en faisant son travail.



2
votes

Si vous exécutez réellement deux boucles de message sur différents threads, il n'ya aucun moyen de faire ce que vous êtes après. Si vous voulez w à posséder b , vous allez avoir à créer B sur le fil principal et invoquer Toutes vos interactions avec B du deuxième fil.


0 commentaires

7
votes

C'est un peu un bogue dans Winforms, Windows prend en charge la fabrication du propriétaire une fenêtre créée sur un autre fil. Il y a un moyen de désactiver ce chèque, quelque chose que vous devriez jamais faire. Sauf quand tu dois que je suppose: xxx

je fais pas savoir si cela est sécurisé à 100%, il pourrait y avoir une interaction WinForms qui vis sur les choses. Vous êtes dans des eaux non testées ici, infestées de requins enfilés.


3 commentaires

Votre suggestion est intéressante. Dans mon cas, je peux m'assurer que le code qui montre la boîte de dialogue n'interférera pas avec le fil d'interface utilisateur principal. Je vais essayer.


Avez-vous trouvé quelque chose de plus en plus sur la sécurité de l'approche ci-dessus? Je voudrais faire cela (avoir une forme propre une forme qui est liée à un fil différent), mais voir deux préoccupations: (1) montrant un formulaire qui appartient à un autre appellera propriétaire.addownedform qui n'est probablement pas thread-coffre-fort; mieux faire l'action sur le fil du formulaire du propriétaire; (2) Si deux formes liées à différents threads tentent de se montrer simultanément, on pourrait définir checkforillegalcrossthreadcalls = true entre le temps que l'autre définit false et le temps qu'il effectue l'opération qui l'oblige à être faux .


Apparemment, une autre solution existe, où vous passez le parent .handle à la procédure du thread en tant que paramètre, et à l'intérieur de la procédure Créer un natifwindow à partir de cette poignée et transmettez-le à .Show () . Ensuite, il n'est pas nécessaire d'éteindre le CheckforillegalcrossthreadCalls .