12
votes

Impasse lors de l'appel du fil de l'interface utilisateur d'un fil de travail

J'ai une impasse lorsque j'invoque le fil de l'interface utilisateur d'un fil de travail. En effet, le thread du travailleur est bloqué sur la ligne d'invoque: xxx pré>

la chose étrange est que le fil de l'interface utilisateur (qui, corrige-moi si je me trompe, est le fil principal) est au ralenti. P>

Y a-t-il un moyen de: P>

  1. Voir quel fil je suis en train d'essayer d'invoquer? Li>
  2. Voyez ce que dit le fil de fil? Li> ol>

    Nous pouvons voir dans l'image ci-dessous, le thread du travailleur (ID 3732) bloqué sur la ligne d'invocation, et le maintien est inactif dans la fonction principale de l'application. P>

    texte alt p>

    EDIT: Voici la pile du fil principal: p>

    text alt p>

    EDIT2: En fait, j'ai fait une deuxième fois le programme une seconde fois et Voici ce que la pile semble: p>

    text alt p>

    Edit3: Solution de contournement trouvé Strong> P>

    J'ai enfin trouvé une solution de contournement. Le problème est apparemment dû à une course d'emballage ASYNC problème de condition. La solution de contournement doit utiliser Begininvoke et l'attendre avec un délai d'attente. Quand il est temps de sortir, appelez-l'à nouveau et en boucle jusqu'à ce qu'il revienne enfin. La plupart du temps, cela fonctionne réellement sur le deuxième appel. P>

    IAsyncResult ar = mInterfaceTraitement.BeginInvoke(d, new object[] { psFamille });
                while (!ar.AsyncWaitHandle.WaitOne(3000, false))
                {
                    ar = mInterfaceTraitement.BeginInvoke(d, new object[] { psFamille });
                }
                // Async call has returned - get response
                ucAvancementTrtFamille mucAvancementTrtFamille = (ucAvancementTrtFamille)mInterfaceTraitement.EndInvoke(ar);
    


4 commentaires

Pouvez-vous poster ce que le d délégué fait?


Et ceci est une application WinForms ou WPF, non?


Le délégué crée simplement un contrôle graphique (à ce stade que cela ne l'ajoutez même à aucune forme). J'utilise des winforms.


Y a-t-il une possibilité que le fil de l'interface utilisateur attend sur le fil de travailleur à un moment donné?


5 Réponses :


2
votes

Avez-vous essayé d'utiliser begininvoke au lieu de invoquer ? begininvoke est asynchrone.


2 commentaires

Oui mais begininvoke ne bloque pas l'appelant. C'est juste une suggestion, bien que oui, cela n'aurait pas d'importance.


SimpleCoder, l'OP veut une valeur de retour de l'invoke. Begininvoke ne peut pas simplement remplacer ici.



0
votes

Avez-vous essayé d'utiliser un travailleur d'arrière-plan à la place. Si vous utilisez cela, cela vous fera économiser beaucoup de cet appel.Invoke et appels invoqués.
Je crois que si vous créez un nouveau thread et que vous le faites exécuter la ligne que vous affichez, vous n'aurez pas de blocage. Je vais essayer de trouver un vieux code de mien et posterai-le ici.


0 commentaires

5
votes

Le fil principal n'a pas l'air inactif. Votre coup d'écran montre l'emplacement actuel sur ECM.PROGRAM.MAIN. Cela ne peut pas être correct, s'il est inactif, il est à l'intérieur de l'application.Run (), pompant la boucle de message. Qui est requis pour appeler () à compléter.

double-cliquez sur le fil principal et passez à la fenêtre de la pile d'appels pour savoir ce que c'est vraiment.


3 commentaires

Eh bien, vous avez raison: c'est en application.Run (), qui est dans mon ECM.PROGRAM.MAIN. Voir mon édition: il montre la pile du fil principal.


Oui, on dirait que ça me pompait aussi. Rugueux. Configurez le serveur de symboles, activer le débogage du code non géré et vous montrer la pile d'appels du fil à impasse.


Il semble que l'emballage ASYNC ait une question de condition de course. Voir ma troisième modification avec la solution que j'ai trouvée.



2
votes

Vous êtes correct. Le thread principal est le point d'entrée à l'application qui est normalement l'emplacement de l'appel à application.run qui obtient la boucle de message. Donc, cela devrait être le fil d'interface utilisateur à moins que vous n'ayez fait quelque chose hors de l'ordinaire en ce qui concerne la boucle de message qui est improbable.

Dans la fenêtre de thread, vous pouvez cliquer avec le bouton droit de la souris sur le thread principal et sélectionner le commutateur pour modifier le contexte de débogage sur ce fil. La fenêtre de pile d'appels affichera ensuite l'emplacement de la méthode d'exécution en cours.

Si le fil de votre travailleur est vraiment bloqué sur le Control.invoke L'appel et le thread d'interface utilisateur est inactif lorsque vous prétendez que le problème pourrait être avec l'exécution des instructions au sein du délégué qui est marshalé. ou la boucle de message comme non encore commencé. Le plus tard semble plausible car votre écran affiche l'emplacement du fil principal comme principal .


1 commentaires

Je modifie ma question et ajoute la pile du fil principal. J'ai activé l'option "Afficher le code externe".



0
votes

Utilisez-vous Visual Studio 2008? Si la réponse est oui, vous devriez essayer avec Visual Studio 2010. C'est un bug connu.

bonne chance!


0 commentaires