Mehrere Threads, die auf ListBox zugreifen...

93Current

Grünschnabel
Hallo Leute,

ich habe folgendes Problem: Ich erzeuge mehrere Threads, die verschiedene Dinge tun (aus DB Daten auslesen, Logging u.a.). Alle diese Threads schreiben Nachrichten über einen Delegaten in eine ListBox des Hauptformulars. Im Hauptformular gibt es eine entsprechende Funktion, die per 'BeginInvoke' den Haupt-Thread bedient. Schon ab zwei Threads gibt es bei mir nun den unerwünschten Effekt, daß der Haupt-Thread (in dem sich das Formular befindet) so gesperrt wird, daß sich weder das Formular mit der Maus bewegen läßt, noch irgend welche Buttons auf Mausaktionen reagieren. Leider helfen auch Thread.Sleep(...) oder Application.DoEvents() nicht. Alle Beispiele, die ich zum Thema Threads->Invoke->Control gefunden habe, behandeln nur einen Thread. Kann mir jemand sagen, was ich tun muß, damit das Hauptformular auch bei mehreren Threads trotzdem noch bedienbar bleibt?

Danke schon mal im Voraus!
93C.
 
Hi,

wenn die mehrere Threads (auch wenn abwechselnd) soviel Daten an den UI-Thread rüberschaufeln, dass dieser die ganze Zeit zu tuen hat wird die UI halt geblockt. Hier muss man gucken, ob man nicht die Benutzerinteraktion irgendwie höher priorisieren kann, sodass wenn ein Benutzer etwas klickt/drückt die anderen Threads mit dem Nachrichten schicken solange warten bis wieder die "Leitung" frei dafür ist.

Ich habe auf msdn einen interessanten Artikel zu deinem Problem gefunden, vielleicht kannst du mit dem dies sogar anders/besser lösen.

Gruß
RudolfG
 
Super, RudolfG,

das sieht nach der Lösung aus, die ich gesucht habe. Danke, ich werde mir das gleich mal anschauen.

(P.S.: Daß die Blockade an der Datenmenge liegt, habe ich mir schon gedacht ;-))

Ich melde mich dann nochmal...

Grüße!
93C.
 
Hi !

Ich hatte vor geraumer Zeit mal ein Problem mit der ListBox als ich massig Einträge auf einen Schlag einfügen wollte. Das Problem war, dass die ListBox nach dem Einfügen eines Items komplett neu gezeichnet wird.

Also ein Element einfügen, ListBox neuzeichnen, Element einfügen, LB neuzeichnen... Und das 500 mal oder so.

Ich hab das am Ende damit gelöst, dass ich das automatische Neuzeichnen verhindert, meinen Kram eingefügt und dann das Neuzeichnen wieder eingestellt habe.

Vielleicht kannst du in deinem Programm deine Nachrichten ne halbe Sekunde lagern und dann sie ebenfalls zusammen einfügen. Ich glaube das Ausschalten des Neuzeichnens ging ganz einfach dadurch, dass man dem Objekt sagt, dass man eine eigene Zeichnenroutine hat.
 
Hallo nochmal,

also, ich habe die 'AsyncUtils', wie im Beispiel beschrieben eingebaut. Bei einem Thread funktioniert die Interaktion mit dem Formular (Ziehen, Buttons) hervorragend. Bei zwei parallelen Threads funktioniert das Ziehen nicht mehr, das Abbrechen per Button funktioniert noch. Ab drei parallel laufenden Threads funktioniert dann gar nichts mehr. Ich habe in meiner Anwendung fünf parallel laufende Threads.

@
RedWraith
Danke für den Tip - das teste ich auch nochmal...

Grüße!
93C.
 
Für das Einfügen von vielen Elementen hintereinander gibt es meistens eine AddRange-Methode. Also ein paar Daten sammeln, wie RedWraith geschrieben hat, und dann AddRange statt Add aufrufen. Um das Neuzeichnen brauchst du dich dann nicht mehr zu kümmern.
 
Hallo nochmal,

auch 'RedWraith's Idee mit der Liste hat nicht gleich funktioniert. Letztendlich hat mir mein Kumpel den besten Tip gegeben: Mit Mutex.WaitOne() sperren, dann Daten in ListBox schreiben, dann Mutex.Release(). Das funktioniert auch mit 10 Threads.

@Shakie
Leider verwende ich eine ListBox, die ein User von CodeProject geschrieben hat. Da gibt es keine Funktion 'AddRange()'.

Gruß und Danke für Eure Antworten
93C.
 
Zurück