Laden...

Controls in anderem Thread erzeugen als das Form [==> auf keinen Fall / Liste der Alternativen]

Erstellt von Bona vor 13 Jahren Letzter Beitrag vor 13 Jahren 7.654 Views
Information von herbivore vor 13 Jahren

Dies ist ein Thread, auf den aus der FAQ verwiesen wird. Bitte keine weitere Diskussion, sondern nur wichtige Ergänzungen und diese bitte knapp und präzise. Vielen Dank!

B
Bona Themenstarter:in
8 Beiträge seit 2010
vor 13 Jahren
Controls in anderem Thread erzeugen als das Form [==> auf keinen Fall / Liste der Alternativen]

Hallo,
ich weiss das Thema Thread gab es schon seht oft.
Habe mir den Thread-Faq ([FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke)) durchgelesen und wurde bei einem Punkt nicht schlauer.
Und zwar bei dem.:

Parent-Child-/Owner-Owned-Beziehungen

Wenn man zwei Forms/Controls in eine z.B. Parent-Child-Beziehung zueinander setzt (z.B. durch form1.Controls.Add (textBox1)), müssen beide Forms/Controls im selben Thread erzeugt worden sein. Controls, die in Beziehung stehen, führen untereinander Zugriffe aus und die wären dann fälschlich threadübergreifend, wenn die beiden Forms/Controls in unterschiedlichen Threads laufen würden. Man darf also insbesondere nicht das Form in einem und seine Controls in einem anderen Thread erzeugen. Sinnvollerweise sollte es immer nur einen GUI-Thread geben.

Ich meine Ok klingt alles logisch, aber wie sollte man vorgehen, wenn man in einem Thread ein Control erzeugen möchte, der danach auf der Form geaddet werden soll..?
Geht es überhaupt, oder muss ich nach eine andere Lösung suchen..?
(z.B. den Control in den Haupt-Thread deklarieren)

5.742 Beiträge seit 2007
vor 13 Jahren

aber wie sollte man vorgehen, wenn man in einem Thread ein Control erzeugen möchte, der danach auf der Form geaddet werden soll..?

Nein, das geht nicht.
Du musst auch die Erstellung des Controls in den GUI-Thread verlagern.

49.485 Beiträge seit 2005
vor 13 Jahren

Hallo Bona,

das Erzeugen der Controls geht immer so schnell, dass keine Notwendigkeit besteht, dies in einen Thread auszulagern. Außer es ist die schiere Anzahl der Controls (> 100), die die Performance-Problem verursacht. Dann muss man die Anzahl der Controls reduzieren.

Wenn es Performance-Probleme gibt, dann üblicherweise bei der Beschaffung der anzuzeigenden Daten. Die Beschaffung kann und sollte man dann in einen extra Thread auslagern.

Manchmal dauert auch das reine Füllen (sehr) großer Datenmengen in das Control zu lange. Da gibt es verschiedene Ansätze:
*Das Reduzierenden der Datenmenge sollte die erste Überlegung sein, weil das nicht nur das Füllen signifikant beschleunigt, sondern Benutzer durch großen Datenmengen sowieso oft überfordert sind. Man beschleunigt dadurch nicht nur die Anwendung, sondern entlastet gleichzeitig den Benutzer.

*Manche Controls haben eine BeginUpdate-Methode, die das Füllen mitunter signifikant beschleunigt.

*Manche Controls haben einen VirtualMode, durch den immer nur die gerade sichtbaren Einträge ins Control gefüllt werden müssen.

*Bei manchen Controls kann man verzögertes Laden (lazy loading) verwenden, z.B. beim TreeView, siehe Verzögertes Laden von Daten im TreeView.

*Manchmal kann es nötig sein, auf ein anderes Control auszuweichen, z.B. eine Autocomplete-TextBox statt einer ComboBox zu verwenden, nicht nur weil sich TextBox.AutoCompleteCustomSource wesentlich schneller füllen oder binden lässt als ComboBox.Items, sondern weil es auch für den Benutzer einfacher zu bedienen ist.

*Das Füllen einer TextBox durch oft wiederholtes textBox1.Text += ... kann sehr lange dauern. Da ist es besser, den Text erst per StringBuilder zusammenzubauen und dann auf einen Rutsch an die TextBox zuzuweisen (siehe [Artikel] Strings verketten: Performance-Betrachtung). Wenn das nicht möglich ist - z.B. weil der gesamte Text gar nicht auf einmal vorliegt - sollte man statt += wenigstens TextBox.AppendText verwenden.

*Wenn keine der genannten Maßnahmen hilft, kann man das Füllen zumindest in mehrere Häppchen aufteilen. Die Schleife über alle Häppchen kommt dann in den Worker-Thread, aber das eigentliche Füllen jedes Häppchens muss dann per Control.Invoke wieder aus dem GUI-Thread erfolgen, siehe [FAQ] Warum blockiert mein GUI? und [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke). Allerdings muss man dann damit rechnen, dass Benutzereingaben schon erfolgen, obwohl das Füllen noch nicht komplett ist.

herbivore

PS: Zum Reduzieren der Anzahl der Controls es viele Möglichkeiten, u.a.:* das simple Entschlacken der Form,

Suchhilfe: 1000 Worte

B
Bona Themenstarter:in
8 Beiträge seit 2010
vor 13 Jahren

Danke Leute für die ausführliche Aufklärung..!