Voici le problème que j'ai: Je dois m'assurer qu'un objet est instancié sur le thread UI. Si ce n'est pas le cas, il devrait lancer une exception. Mais comment puis-je vérifier dans une méthode si elle s'exécute sur le thread de l'interface utilisateur? Remarque: je ne souhaite pas transmettre d'informations dans le constructeur de l'objet. Le candidat idéal serait le DispatcherSynchronizationContext (implémentation WPF de SynchronizationContext) qui contient en interne une référence à Dispatcher qui fait référence au thread auquel il est associé, mais malheureusement ce champ est privé, donc je n'ai aucun moyen d'y accéder.Comment puis-je savoir si la méthode s'exécute sur un thread UI ou pas de manière découplée?
Répondre
Petite clarification, bien qu'il y ait typiquement seulement 1 filetage UI, il peut y avoir beaucoup de filetage UI. Cela est vrai pour WPF et WinForms.
Le meilleur moyen que j'ai trouvé pour réaliser ceci est cependant avec un SynchronizationContext. WPF et WinForms établiront un SynchronizationContext sur tous les threads sur lesquels ils exécutent l'interface utilisateur. C'est la fonction que j'utilise si je ne suis pas lié à un modèle d'interface utilisateur particulier.
public bool IsPossiblyUIThread() {
return SynchronizationContext.Current != null;
}
Remarque, il n'est en aucun cas infaillible. Il est possible pour les composants non-UI d'établir un SynchronizationContext et cela retournera true pour un thread de travail simple. D'où le nom non-autorisé.
Un légèrement un moyen plus fiable pour ce faire est la suivante. Mais il vous oblige à référencer au moins une partie de WPF à mettre en œuvre.
public bool IsLikelyWpfUIThread() {
var context = SynchronizationContext.Current;
return context != null && context is DispatcherSynchronizationContext;
}
Dispatcher.CheckAccess() renvoie true si votre code fonctionne sur le même fil que le répartiteur. Cela devrait fonctionner s'il n'y a qu'un Dispatcher/UIThread.
Cela peut être vrai, mais notez que le Dispatcher est toujours associé au thread sur lequel il a été créé. Donc, en utilisant Dispatcher.CheckAccess() ne vous aide pas beaucoup si l'objet a été créé sur un autre thread. –
Oui, cela semble être le meilleur moyen. Merci beaucoup! –