Warum ist es nicht möglich, eine ObservableCollection aus einem anderen Thread zu aktualisieren?

8

In einer WPF-Anwendung mit mehreren Threads ist nicht möglich , um ein ObservableCollection von einem anderen Thread als WPF-Fenster-Thread zu aktualisieren.

Ich weiß Es gibt Problemumgehungen , daher ist meine Frage nicht, wie man " vermeiden kann. Dieser Typ von CollectionView unterstützt keine Änderungen an seiner SourceCollection von einem Thread, der sich von der Dispatcher-Thread " Ausnahme unterscheidet.

Meine Frage ist: Warum gibt es eine solche Ausnahme? Warum war es nicht möglich, Sammlungsaktualisierungen von einem beliebigen Thread zuzulassen?

Ich persönlich sehe keinen Grund, die UI-Aktualisierung zu blockieren, wenn ObservableCollection von anderen Threads geändert wird. Wenn zwei Threads (einschließlich paralleler Threads) auf dasselbe Objekt zugreifen, wobei eines auf Änderungen von Objekteigenschaften durch Ereignisse wartet und das andere Änderungen vornimmt, wird es immer funktionieren, zumindest wenn Sperren richtig verwendet werden. Also, was sind die Gründe?

    
Arseni Mourzenko 05.06.2010, 14:04
quelle

2 Antworten

15

Zuerst ... Ich fühle deinen Schmerz. Die Ui-Thread-Beschränkung kann ein Schmerz sein ...

  

Warum können Sie ein Ui-Element nicht von aktualisieren?   ein anderer Thread als der, der es war   erstellt am?

     

Meine Frage ist, warum es ein solches gibt   Ausnahme?

Nun in aller Kürze, Geschichte. Windows ist schon eine Weile her und die Art, in der einige Teile der Gui-Arbeit in Technologien wie COM und Ähnlichem eingebettet sind ... so etwas zu ändern ist nicht trivial ... wäre sehr leicht, etwas zu kaputt zu machen. Ich bin mir sicher, dass es viele andere Probleme gibt ... aber jemand, der klüger ist als ich, müsste sie erklären. Ich glaube, das WPF-Team wollte diese Einschränkung wirklich beseitigen und sie arbeiteten ziemlich hart daran ... am Ende denke ich, dass die Anzahl der Änderungen am Kernbetriebssystem nicht durchführbar war ... also zogen sie weiter ... Ratten.

  

Warum war es nicht möglich zu erlauben?   Sammlung Updates von jedem Thread?

Es war und ist möglich ... Etwas threadsicher zu machen kostet immer etwas Leistung und erhöht die Komplexität. In den meisten Fällen erfordert die Anwendung keinen Multi-Thread-Zugriff. Es ist wichtig zu verstehen, dass Microsoft in den meisten Fällen nach den gleichen Regeln spielt, die wir auch anwenden. Wenn sie die ObservableCollection threadsicher gemacht hätten ... hätten sie die gleichen Werkzeuge benutzt, die wir haben ... Schlösser, Monitore usw. Sie können die Ui-Fadenregel nicht mehr brechen als wir ... keine Magie ... gleiche Regeln.

  

Ich weiß, dass es Umgehungslösungen gibt, also meine   Frage ist nicht, wie man das "This   Typ von CollectionView nicht   Unterstützung Änderungen an seinem   SourceCollection aus einem Thread   unterscheidet sich vom Dispatcher-Thread "   Ausnahme.

Es gibt keine Problemumgehungen ... Es gibt keine Problemumgehung. Die ObservableCollection ist kaputt. Sie ist nicht threadsicher. Sie müssen es oder thread-sicher darauf zugreifen. Dies gilt auch für alles, was nicht threadsicher ist ... wenn Sie es thread-sicher brauchen, dann machen Sie es so. Wenn Sie Threads verwenden, dann wissen Sie über Sperren und solche ... verwenden Sie sie..das sind sie wofür.

  

... Block UI Update wann   ObservableCollection wird geändert von   andere Threads .... es wird immer funktionieren,   zumindest wenn Schlösser benutzt werden   richtig ....

Wenn Schlösser richtig benutzt werden ... Genau! Auch hier hätte Microsoft diese Sperren setzen können, aber aus gutem Grund nicht. Sie können die Sperren setzen. Oder Sie verwenden andere Taktiken, die Ihnen thread-sicheren Zugang geben .... viele Optionen.

Die Task Parallel Library in .net4.0 bietet einige neue Tools zur Lösung dieser Probleme. Einen Kontext für eine Aufgabe oder einen Thread zu setzen, ist besonders nützlich ...

%Vor%

Denken Sie nicht an die Thread-Affinitätsanforderungen von Ui Elements als etwas, worüber Sie arbeiten können ... es ist einfach so, wie es funktioniert.

C # und .Net haben viele Tools, die Sie verwenden können, die Threading ein bisschen weniger zum Albtraum machen. Benutze sie ... sie können Spaß machen.

Ich gehe auf einen Rauch.

    
Rusty 05.06.2010, 16:04
quelle
10

Wenn Ihre Sammlung an Benutzeroberflächenelemente gebunden ist, hören diese Benutzeroberflächenelemente das Ereignis CollectionChanged der Sammlung ab, und dieses Ereignis wird im Thread ausgelöst, auf dem Sie die Sammlung aktualisieren.

Das Problem liegt also bei den Benutzeroberflächenelementen, auf die nur aus dem Thread zugegriffen werden kann, auf dem sie erstellt wurden, und nicht mit der Sammlung selbst.

    
treaschf 05.06.2010 14:10
quelle