12
votes

Control.invoke () bloque l'application

Je montre une animation pendant que mon contrôle charge les données. Lorsque le fil se termine, je cache l'animation et montrez le contrôle. Donc, j'exécute ce code à partir d'un thread:

protected virtual void EnableBackControl()
{
    if (overlayAnimation.TargetControl != null)
    {
        overlayAnimation.TargetControl.BringToFront();
    }

    overlayAnimation.SendToBack();
    overlayAnimation.Enabled = false;
    overlayAnimation.Visible = false;                      


3 commentaires

Y a-t-il un motif discernable à l'époque où il se bloque?


@No, seulement "parfois". Agaçant.


Documentez la déclaration exacte qu'il est suspendu, postez la trace de la pile.


5 Réponses :


4
votes

exécuté dans le débogage, faire accrocher l'application, puis pause débogage dans Visual Studio et inspecter des threads.


3 commentaires

Quel genre de réponse est-ce? J'ai joint le processus avec le débogueur, j'ai fait une pause et j'ai inspecté les threads. C'est la raison pour laquelle je sais que le thread est dans le premier bloc de code et le fil principal est dans le second.


@Daniel Peñalba C'est une sorte de solution qui m'aide. Parce que lorsque vous faites cela, vous pouvez voir des lignes exactes où le fil est suspendu.


Je l'ai fait. La ligne mise en surbrillance lorsque je casse que tous les threads sont superchauffis.visible = false; mais généralement le studio visuel (presque 2003) s'arrête dans la ligne précédente. Seulement parfois, c'est la raison pour laquelle je ne suis pas sûr de si la ligne ou la précédente.



23
votes

Notez que contrôler.invoke est synchrone, il va donc attendre activebackcontrol () pour revenir. Pensez à utiliser contrôler.begininvoke , que vous pouvez "tirer et oublier".

Voir cette réponse: Quelle est la différence entre invoke () et débutinvoke ()


0 commentaires

7
votes

Je rencontre des problèmes auparavant lorsque j'exécute un fil d'antécédent tandis que mon fil principal est toujours occupé - cela donne l'impression que l'application est suspendue, car le .Invoke suffit juste là-bas, en attendant la Fil principal pour répondre qu'il fait attention. Causes possibles:

  • Votre fil principal est bloqué en attente de quelque chose
  • Votre formulaire principal a eu actuellement une boîte de dialogue modale. Il n'écoute donc pas de nouvelles demandes
  • Votre fil principal est en train de tourner, soit en vérifiant continuellement si quelque chose est terminé ou de nouveau travail. Dans mon cas, le fil principal a passé la première minute à filer des fils de fond dans une boucle serrée, de sorte qu'il n'écoutait aucune demande .Invoke à partir de threads de fond.

    Lorsque vous attachez le débogueur, faites une attention particulière à ce que votre thread de contrôle de contrôle principal est-ce que votre manque de contrôle de contrôle - Je soupçonne que son manque d'attention est la cause de votre problème. Si vous identifiez que c'est une boucle serrée dans votre fil principal qui ne répond pas, essayez d'insérer un .Deevents dans la boucle, qui mettra en pause l'exécution et forcera le thread principal pour vider la pompe de message et l'itinérance Demandes.


1 commentaires

Merci, c'était mon cas, et l'application.Deevents () a fait l'affaire.



0
votes

Ce que j'ai découvert, c'est que le dessin / peinture réel des contrôles peut être assez lent, en particulier si vous en avez beaucoup d'entre eux et / ou utilisez une double tampon pour rafraîchir en douceur. J'utilisais Begininvoke pour mettre à jour un contrôle ListView à partir de données que je recevais à partir d'une prise. Parfois, les mises à jour se produisaient si vite qu'il gelage de l'application. J'ai résolu ceci en écrivant tout ce que j'ai reçu dans les sockets Async reçoivent une file d'attente, puis dans un fil séparé en détestant les données et en utilisant beginupdate et endupdate sur la liste de liste et de faire toutes les mises à jour en suspens entre les deux. Cela découpe une tonne de redessinement supplémentaire et a rendu l'application beaucoup plus réactive.


0 commentaires

0
votes

Vous devez utiliser begininvoke inesté invoquer Voir ceci Lien


0 commentaires