Comment résolvez-vous les problèmes d'interface utilisateur WPF?
-
01-07-2019 - |
Question
Je travaille sur une application WPF qui présente parfois des problèmes étranges et semble se bloquer dans l'interface utilisateur. C'est incohérent, cela se produit dans différentes pages, mais cela arrive assez souvent que c'est un gros problème. Je devrais mentionner que ce n’est pas un véritable blocage, comme décrit ci-dessous.
Ma première pensée a été que le problème était lié aux animations de certains boutons car ils sont utilisés sur la plupart des pages, mais après leur suppression, les blocages se produisent toujours, bien qu’apparemment un peu moins souvent. J'ai essayé de pénétrer dans le débogueur lorsque le blocage se produit; Cependant, il n'y a jamais de code à afficher. Aucun de mes codes n'est en cours d'exécution. J'ai également remarqué que le message "se bloquer". n'est pas complet. J'ai un code qui me permet de faire glisser le formulaire (il n'a pas de bordure ni de titre) qui continue à fonctionner. J'ai aussi mon bouton de gain gagné qui fonctionne lorsque je clique dessus. Un clic sur les boutons semble fonctionner lorsque mon code est exécuté, mais l'interface utilisateur ne se met jamais à jour pour afficher une nouvelle page.
Je cherche des conseils, des outils ou des techniques pour dépister cet étrange problème. Si vous avez des idées, je les apprécierai grandement.
EDIT: Cela vient de se reproduire, donc cette fois-ci, lorsque j’ai essayé de pénétrer dans le débogueur, j’ai choisi de "montrer le désassemblage". Cela m'amène à MS.Win32.UnsafeNativeMethods.GetMessageW. La trace de la pile suit:
[Managed to Native Transition]
WindowsBase.dll! MS.Win32.UnsafeNativeMethods.GetMessageW (réf. System.Windows.Interop.MSG, msg, System.Runtime.InteropServices.HandleRef hWnd, int uMsgFilterMin, int uMsgFilterMax) + 0x15 fois. WindowsBase.dll! System.Windows.Threading.Dispatcher.GetMessage (réf. System.Windows.Interop.MSG, msg, System.IntPtr hwnd, int minMessage, int maxMessage) + 0x48 octets WindowsBase.dll! System.Windows.Threading.Dispatcher.PushFrameImpl (System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame}) + 0x8b octets WindowsBase.dll! System.Windows.Threading.Dispatcher.PushFrame (cadre System.Windows.Threading.DispatcherFrame) + 0x49 octets
WindowsBase.dll! System.Windows.Threading.Dispatcher.Run () + 0x4c octets
PresentationFramework.dll! System.Windows.Application.RunDispatcher (object ignore) + 0x1e octets
PresentationFramework.dll! System.Windows.Application.RunInternal (fenêtre System.Windows.Window) + 0x6f octets PresentationFramework.dll! System.Windows.Application.Run (fenêtre System.Windows.Window) + 0x26 octets PresentationFramework.dll! System.Windows.Application.Run () + 0x19 octets WinterGreen.exe! WinterGreen.App.Main () + 0x5e octets C # [Indigène à la transition gérée]
[Géré à la transition autochtone]
mscorlib.dll! System.AppDomain.nExecuteAssembly (assembly System.Reflection.Assembly, string [] args) + 0x19 octets mscorlib.dll! System.Runtime.Hosting.ManifestRunner.Run (bool checkAptModel) + 0x6e octets mscorlib.dll! System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly () + 0x84 octets mscorlib.dll! System.Runtime.Hosting.ApplicationActivator.CreateInstance (System.ActivationContext activationContext, chaîne [] activationCustomData) + 0x65 octets mscorlib.dll! System.Runtime.Hosting.ApplicationActivator.CreateInstance (System.ActivationContext activationContext) + octets 0xa mscorlib.dll! System.Activator.CreateInstance (System.ActivationContext activationContext) + 0x3e octets
Microsoft.VisualStudio.HostingProcess.Utilities.dll! Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone () + 0x23 octets
mscorlib.dll! System.Threading.ThreadHelper.ThreadStart_Context (état de l'objet) + 0x66 octets
mscorlib.dll! System.Threading.ExecutionContext.Run (System.Threading.ExecutionContext executionContext, rappel System.Threading.ContextCallback, état de l'objet) + 0x6f octets
mscorlib.dll! System.Threading.ThreadHelper.ThreadStart () + 0x44 octets
La solution
Essayez de supprimer le comportement sans bordure de votre fenêtre et voyez si cela vous aide. De plus, êtes-vous BeginInvoke () ou Invoke () dans des opérations de longue durée?
Autre chose à considérer: lorsque vous introduisez votre code dans votre code, essayez d’examiner les threads autres que votre thread principal. L’un d’eux peut bloquer le thread d’UI.
Autres conseils
Votre application WPF pourrait être suspendue en raison de problèmes de performances. Essayez d’utiliser Perforator pour voir si des pièces sont rendues par un logiciel ou si votre application utilise trop de RAM vidéo.
Snoop est un excellent outil. Vraiment agréable pour regarder quels objets WPF sont affichés sur l’arbre visuel à un moment donné. Je ne sais pas dans quelle mesure cela vous aidera, mais il est possible que vous bloquiez le fil de l'interface utilisateur avec de nombreuses tâches supplémentaires. Snoop peut vous aider à localiser ce qui est affiché à l'écran pour vous donner une idée de ce qu'il faut rechercher.
J'ai supprimé le comportement sans frontières proposé par Bob King. À ce jour, cela semble s’être débarrassé du problème.
Maintenant, la question est de savoir pourquoi et comment puis-je résoudre le problème? Le produit est conçu pour ne comporter aucune bordure avec des coins arrondis et des parties transparentes.
Hourra, ... il semble que le problème ne soit pas lié aux fenêtres sans frontières (du moins dans mon cas).
La performance de AllowsTransparency
est définie sur true. Il semble qu'il y ait tellement de succès que le tout peut accrocher le fil de l'interface utilisateur. Comportement très étrange. Peut être lié à ce billet