Sono molto confuso da questo e sta iniziando a farmi mettere in discussione tutta la mia comprensione del sistema di risorse WPFPerché Freezables è già stato congelato e ha un Dispatcher nullo (uguale agli Stili) quando è archiviato in Application.Resources?
Ho un'applicazione multi-finestra in cui ogni oggetto derivato da Windows viene eseguito su un thread separato con dispatcher separato.
Thread t = new Thread(() => {
Window1 win = new Window1();
win.Show();
System.Windows.Threading.Dispatcher.Run();
});
t.SetApartmentState(ApartmentState.STA);
t.Start();
Ho un dizionario risorse Dictionary1.xaml con un oggetto Style chiamato al suo interno (imposta solo la proprietà di sfondo di rosso ed è mirato ad una TextBox). Nella mia app.xaml faccio riferimento a Dictionary1.xaml tramite la raccolta ResourceDictionary.MergedDictionaries. Nella XAML delle altre finestre ho una risorsa statica per la chiave di stile in un controllo casella di testo, che funziona.
Sono in grado di aprire più finestre, ma non dovrei ricevere errori di cross-threading? Nel costruttore di una delle classi finestra ho fatto questo:
Style s = (Style)TryFindResource("TestKey");
Console.WriteLine(((Setter)s.Setters[0]).Property.Name); // no problem
s.Dispatcher == this.Dispatcher // false
Dal momento che un oggetto Style è derivato da DispatcherObject, non significa che è accessibile solo al thread che lo possiede? E se un oggetto è definito in un ResourceDictionary, non significa che per impostazione predefinita è un'istanza statica? Come è anche in grado di funzionare? Perché non ricevo un errore di cross-threading?
(ho erroneamente riportato una domanda che in quanto cancellato su un errore di threading croce che è stato causato da qualcos'altro)
Sono molto confuso da questo - ho pensato solo oggetti Freezable congelati erano condivisibili attraverso i thread. Perché sono autorizzato ad accedere a DispatcherObject su altri thread?
Sì, ho provato CheckAccess e è tornato true mentre VerifyAccess non ha generato un'eccezione . ReferenceEquals restituisce anche false prevedibilmente. Grazie per avermi ricordato che DispatcherObject non è un oggetto magico e che l'affinità del thread viene applicata da chiamate manuali a VerifyAccess() - ottimo punto/promemoria! Molto confuso ancora – blue18hutthutt
Come ulteriore test, ho appena creato un nel dizionario delle risorse. Questo dovrebbe creare un nuovo SolidColorBrush non congelato, che per definizione NON dovrebbe essere accessibile su un altro thread e tuttavia ... è AND quando lo richiamo da un'altra finestra - è già congelato! La mia comprensione di come pensavo che WPF funzionasse è semplicemente crollata ... –
blue18hutthutt
Ecco il codice per il metodo Dispatcher.CheckAccess(): "return this.Thread == Thread.CurrentThread;" "this.Thread" è naturalmente l'istanza del thread memorizzata nell'istanza dell'oggetto. Potresti confermare che questo test restituisce anche per te ???? –