Background Thread zum Filelisten einlesen

22/10/2007 - 17:45 von Peter Treier | Report spam
Guten abend zusammen

ich habe dem Auftrag ein Programm zu erstellen, dass mit sehr vielen losen
Files umgehen muss.
Ich muss aus diesem Grund im GUI 4 Contols befüllen (Listviews die ich in
einem Usercontrol eingebaut habe).
Die Listviews werden zum Schluss je um die 250 Eintràge - sprich Files -
enthalten.

Damit das Befüllen der Controls nun nicht das ganze GUI einfrieren, habe ich
mir gedacht 'Packden Prozess im Usercontrol in einen Background Worker'...
Bringt nichts ! Das GUI ist in der Zeit in der die Usercontrols befüllt
werden nicht zu bedienen...

Mach ich da was falsch ? Gibt es bei der Konstellation User Control /
Background Worker etwas spezielles zu beachten ?

Wàre für ein paar Tipp sehr froh !

Gruss & schönen Abend

Peter
 

Lesen sie die antworten

#1 Torsten Kerz
23/10/2007 - 09:23 | Warnen spam
Hallo Peter.

Peter Treier schrieb:
Die Listviews werden zum Schluss je um die 250 Eintràge - sprich Files -
enthalten.
Damit das Befüllen der Controls nun nicht das ganze GUI einfrieren, habe ich
mir gedacht 'Packden Prozess im Usercontrol in einen Background Worker'...



Das Befüllen der Controls muss immer immer im Thread der GUI erfolgen. Du kannst durch einen Backgroundworker also
lediglich die Zeit der Dateiermittlung "einspaaren". Entsprechend wàre es sicherlich sinnvoll, die benötigte Zeit für
die Ermittlung einmal zu messen und zu bewerten, ob sich das in einem Backgroundworker überhaupt lohnt.

Jedenfalls ...
Da GUI-Zugriffe im entsprechenden Thread laufen müssen, sollte dein Backgroundworker die Ergebnisse in einer
Liste/Collection zwischenspeichern. Du hast nun die Wahl, ob Du diese erst vollstàndig am Schluss in die GUI übertràgst
oder z.B. alle ein bis zwei Sekunden. Jede einzelne Datei würde dir den GUI-Thread vermutlich wieder vollstàndig
blockieren. Für die Übergabe an den GUI-Thread kannst Du wahlweise über ReportProgress(percent, userState) auch mit
einer eigenen Invoke-Routine arbeiten.

Bsp für eine Invoke-Routine:
Private Delegate Sub NeueDaten_Delegate(ByVal Dateiliste as Collection)
Private Sub NeueDaten(ByVal Dateiliste as Collection)
If FrmAktivesFenster.InvokeRequired Then
FrmAktivesFenster.Invoke(New NeueDaten_Delegate(AddressOf NeueDaten), Dateiliste)
Else
'Inhalt der Collection ins Listview kopieren
End If
End Sub

Nachdem Du das Zwischenergebnis weitergereicht hast, solltest Du eine NEUE Liste instanzieren, um einen möglichen
Zugriff durch zwei Threads zu unterbinden:

ReportProgress(Prozent, MeineDateiListe)
MeineDateiListe = New Collection

Abschließend sei noch zu sagen, daß das ListView eine "BeginUpdate" und eine "EndUpdate"-Methode besitzt. Diese solltest
Du vor bzw. nach dem Einfügen der neuen Dateinamen verwenden, um das Neuzeichnen des ListViews für jeden einzelnen,
neuen Eintrag zu verhindern.

Gruß,
Torsten.

Ähnliche fragen