Entwickler-Ecke

Sonstiges (.NET) - [Multithreading] Daten übergeben


vreden123 - Di 06.08.13 08:00
Titel: [Multithreading] Daten übergeben
Guten Morgen,

ich habe ein kleines Programm geschrieben das Dateien herunterladen kann.

Das Programm hat 2 Threads. (Einen Hauptthread und einen Thread der die ganze Zeit nach Downloads sucht und die Dateien herunterlädt.)

Der "Download-Thread" ist folgendermaßen aufgebaut.

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
while(true)
{
Sleep(60000); // 60 Sekunden Pause machen
// Nach Downloads suchen
// Anzahl der zu herunterlandenen Dateien zählen
// Dateien nach und nach runterladen
}



Dies macht der "Downlaod-Thread" in einer Endlosschleife.

Mein Problem ist es, dass ich die Anzahl der zu herunterladenen Dateien an den "Haupt-Thread" übergeben und anzeigen lassen möchte.
Da dies ein Threadübergreifender Vorgang ist, muss ich das doch mit einem Invoke machen.
Aber wie mache ich das? Bzw. wie ist die Vorgehensweise?

Ich denke mir das ich in dem "Download-Thread" eine Funktion (mit dem entsprechenden Parameter, Downloadanzahl) aufrufen muss, und die dann ein Event in der MainForm vom Hauptthread auslöst.

Gruß,
vreden123


Webo - Di 06.08.13 09:25

Moin,

da du mit mehr als einem Thread arbeitest muss man zunächst an Threadsynchronisation denken - auf eine Variable/Control/etc. sollte maximal ein Thread zugreifen, die anderen müssen warten, wenn sie gleichzeitig auch daran arbeiten wollen. Dann muss beachtet werden, dass auf grafische Elemente immer nur von dem Thread zugegriffen werden kann, zunächst von dem, der das Element erzeugt hat. Allerdings kann dieser "Besitzer" mit Invoke geändert werden.

Jetzt kommt es darauf an, was du in deiner MainForm mit den Informationen machen willst, für eine einfache Anzeige o.ä. würde folgende Möglichkeit gehen:
- Du greifst vom Download-Thread auf die entsprechende Anzeige zu (lock, invoke nicht vergessen) und änderst dort den Wert der Downloads
- Bei Zugriffen im Hauptthread auf dieses Element muss du dann aber beachten, dass dann ebenso ein lock/invoke nötig ist

Für diese Sache eignet sich Invoke in folgender Form ganz gut:


C#-Quelltext
1:
2:
3:
4:
Invoke( ( MethodInvoker ) delegate {
        object1.Visible = true;
        object2.Visible = false;
    }



Grüße

Webo


vreden123 - Di 06.08.13 09:53

Der "Downloadthread" soll nicht direkt ein Element ändern.
Ziel ist es das sich das Icon was ich in der Taskleiste angelegt habe, bei einem Download animiert/dreht. (Das der User sieht, dass sich was tut)
Sind alle Downloads abgeschlossen, soll die Animiertung stoppen.

Also ich dachte dass ich aus dem Downloadthread per Event eine Funktion in dem Hauptthread aufrufe die das Icon animieren/drehen lässt.
Wenn alle Downloads abgeschlossen sind, muss der Downloadthread per Event in dem Haupthread eine Funktion aufrufen, die die animierung stoppt.

Die Animation lasste ich dann nachher per Timer starten der das Icon entsprechend ändert.
Und stoppen kann ich das ganze indem ich den Timer deaktiviere.

Gruß,
vreden123