Simon: C-Sharp: Zugriff durch Thread auf ein Objekt verweigert bei WPF

Beitrag lesen

Moin,

sorry ich war leider weg, aber nun:

dachte schon, ich wäre dir nicht gut genug ^^. Aber gut, ich bin auch nicht der Super-Guru für WPF.

Multithreading ist ein Thema für sich, da braucht mal viel Hintergrundwissen. Wenn es um C# geht, dann muss man auch noch wissen was die (MS) da eigentlich mit den entspr. Funktionen bezwecken und es ist viel Lesearbeit nötig. Ich habe das jedenfalls nicht alles im Kopf aber im Hinterkopf, dass da irgendwas war. So nun ...

Ein Timer wird öfters ausgeführt.

Es gibt verschiedene Timer-Klassen. Allen gemein ist meistens, dass sie auslösen, wenn ein Intervall überschritten wurde. Dieses automatische Auslösen kann man durch einen Aufruf der entsprechenden Stop-Methode unterbinden oder indem man die Eigenschaft "AutoReset" auf false setzt. Das ist entsprechend der Timer-Klasse nachzulesen. Windows-Forms-Timer haben zudem ein minimales Intervall von 55ms und es kommt auch darauf an, in welchem Kontext dann die Callback-Funktion ausgeführt wird. Aber das ist jetzt nur zur Anmerkung, warum nutzt du einen Timer?

Sinnvollerweise änderst du Daten in deinem Model. Über die Bindung wird die UI davon automatisch benachrichtigt ... egal.

Task.Factory.StartNew(() => {
Dispatcher.Invoke(new Action(() => threadMethode() ));
});


> (Die threadMethode() ruft das f.anmelden() auf und wertet auch gleich das Ergebnis aus [ist aber alles in einem anderen Thread, wodurch der Hauptthread und die GUI nicht einfrieren sollten].)  
  
Das ist ein Schuß von hinten durch die Brust ins Auge. "Dispatcher.Invoke" sorgt ja dafür, dass die Aktion in seinem Kontext (Hauptthread) ausgeführt wird (und blockiert). Dafür brauchst du keinen Thread starten, der die Aktion wieder reflektiert. Den Task solltest du nur für Hintergrundarbeiten anschmeißen. Also Webservice aufrufen und Ergebnis liefern. Danach das Model anpassen, also die Änderungen speichern. Die UI wird automatisch durch die Bindung zu deinem Model aktualisiert. Das Model bzw. Eigenschaften davon sollten via "Dispatcher-Invoke" aktualisiert werden (würde ich jetzt empfehlen).  
  
~~~c++
  
  Task.Factory.StartNew(() => {  
    var result = longrunningtask();  
    model.Status = (result == null ? "Fehler" : "Ok");  
  }, TaskCreationOptions.LongRunning);  

oder auch

  
  Task.Factory.StartNew(() => {  
     var result = longrunningtask();  
     Dispatcher.Invoke(() => {  
       model.Status = (result == null ? "Fehler" : "Ok");  
     });  
  }, TaskCreationOptions.LongRunning);  

Sollte f.anmelden() ansich auf das Model zugreifen, dann ist das ein Fehler im Design. Dafür kannst du aber nichts, das wurde jahrelang so propagiert.