Domanda

In un'applicazione WPF avevo un thread BackgroundWorker che creava un oggetto. Chiamiamo l'oggetto foo.

Codice lavoratore in background:

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);

Ora, quando la classe principale tenta di accedere a FooProperty usando un getter, ottengo un InvalidOperationException: il thread chiamante non può accedere a questo oggetto perché lo possiede un thread diverso.

Se il thread che crea l'oggetto è finito, perché possiede ancora l'oggetto? C'è un modo per aggirare questo.?

È stato utile?

Soluzione

Un oggetto creato in un determinato thread è di proprietà di quel thread. Ecco perché stai ricevendo InvalidOperationException. Se desideri impostare una proprietà in un thread in background, ti consiglio di chiedere al delegato di restituire il valore desiderato e di chiamare SetValue dal thread principale. (thread che ha creato l'oggetto).

Altri suggerimenti

La stragrande maggioranza degli oggetti in WPF ha affinità di thread. Che una volta viene creato su un determinato thread, un oggetto WPF funzionerà solo se utilizzato da quel thread. Questa restrizione viene applicata (diversamente da WinForms) praticamente su ogni operazione eseguita su quell'oggetto.

Dovrai cambiare il tuo codice per creare Foo sul thread dell'interfaccia utente attuale per questo scenario.

Supponendo che SomeClass sia derivato da DispatcherObject , il thread che lo ha creato esegue il pump dei messaggi che è responsabile dell'elaborazione dei messaggi per l'oggetto foo . Pertanto, se quel thread termina, l'oggetto non può più elaborare i messaggi, il che non è una buona idea.

Nella maggior parte dei casi è necessario utilizzare lo stesso thread dell'interfaccia utente per creare tutti gli oggetti dell'interfaccia utente (o qualsiasi altra cosa derivata da DispatcherObject e assicurarsi che venga eseguita per la durata dell'applicazione. Quindi utilizzare il Dispatcher per inviargli messaggi dai tuoi thread di lavoro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top