Question

Dans une application WPF, un thread BackgroundWorker créait un objet. Appelons l'objet foo.

Code de travailleur en arrière-plan:

SomeClass foo = new SomeClass();
// Do some operation on foo

// Set some dependency property on the main class to foo
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (SendOrPostCallback)delegate { SetValue(FooProperty, foo); },
    foo);

Désormais, lorsque la classe principale tente d'accéder à FooProperty à l'aide d'un getter, je reçois une InvalidOperationException: le thread appelant ne peut pas accéder à cet objet car un autre thread le possède.

Si le fil créé pour créer l'objet est terminé, pourquoi possède-t-il toujours l'objet? Y a-t-il quelque chose autour de ça.?

Était-ce utile?

La solution

Un objet que vous créez dans un thread donné appartient à ce thread. C'est pourquoi vous obtenez une exception InvalidOperationException. Si vous souhaitez définir une propriété dans un thread en arrière-plan, il est recommandé que le délégué renvoie la valeur souhaitée et appelle SetValue à partir de votre thread principal. (fil qui a créé l'objet).

Autres conseils

La grande majorité des objets dans WPF ont une affinité de thread. Une fois créé sur un thread particulier, un objet WPF ne fonctionnera que s’il est utilisé à partir de ce thread. Cette restriction est appliquée (contrairement à WinForms) à pratiquement toutes les opérations que vous effectuez sur cet objet.

Vous devez modifier votre code pour que Foo soit créé sur le thread d'interface utilisateur réel pour ce scénario.

En supposant que SomeClass est dérivé de DispatcherObject , le thread qui l'a créé exécute la pompe de messages responsable du traitement des messages pour l'objet foo . . Par conséquent, si ce fil se termine, l'objet ne peut plus traiter les messages, ce qui n'est pas une bonne idée.

Dans la plupart des cas, vous devez utiliser le même thread d'interface utilisateur pour créer tous vos objets d'interface utilisateur (ou tout autre élément dérivé de DispatcherObject et vous assurer qu'il est exécuté pendant toute la durée de votre application. Utilisez ensuite Dispatcher pour lui envoyer des messages à partir de vos threads de travail.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top