Laden...

Threads: Liste der Reihe nach abarbeiten

Erstellt von ArnoNuehm vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.435 Views
A
ArnoNuehm Themenstarter:in
47 Beiträge seit 2010
vor 12 Jahren
Threads: Liste der Reihe nach abarbeiten

Hallo,

ich hab da mal wieder ein kleines Problem.

Ich habe eine Liste mit Downloads die ich abarbeiten will.
Es soll immer nur ein Download aktiv sein.

Mein aktueller Code sieht so aus...

private void downloadStarten_Click(object sender, EventArgs e)
{
	if (listView1.Items.Count > 0)
	{
		for (int i = 0; i < listView1.Items.Count; i++)
		{
			string downloadName = listView1.Items[i].SubItems[1].Text;
			string url = myObject.getDataLink(downloadName);
			Thread thread = new Thread(delegate() { myDlObject.download(url); });
			thread.Start();
		}
	}
	else MessageBox.Show("Keine Downloads in der Liste !", "Fehler");
}

Hier wird jedoch alles direkt gestartet.
Wie stelle ich es an das ich erst nach erfolgreichem beenden eines Threads den nächsten starte?

Gruß

Arno

P
66 Beiträge seit 2009
vor 12 Jahren

Moin!

Dann solltest du vielleicht die komplette Schleife in einen Thread legen, anstatt für jeden einzelnen Download einen eigenen Thread zu starten.

Gruß,
phreakadelle

Edit:


        for (int i = 0; i < listView1.Items.Count; i++)
        {
            string downloadName = listView1.Items[i].SubItems[1].Text;
            string url = myObject.getDataLink(downloadName);
            myDlObject.download(url);
        }

Also, die Schleife in dieser Form in einem Thread unterbringen.

...

A
ArnoNuehm Themenstarter:in
47 Beiträge seit 2010
vor 12 Jahren

Danke, das versuch ich gerade mal.

So sieht der Code nach dem Umbau aus...

private void downloadStarten_Click(object sender, EventArgs e)
{
	if (listView1.Items.Count > 0)
	{
		Thread thread = new Thread(downloadWorker);
		thread.Start();
	}
	else MessageBox.Show("Keine Downloads in der Liste !", "Fehler");
}

private void downloadWorker()
{
	this.Invoke(new Action(() =>
	{
		for (int i = 0; i < listView1.Items.Count; i++)
		{
			string downloadName = listView1.Items[i].SubItems[1].Text;
			string url = myObject.getDataLink(downloadName);
			int downloadItemId = i;
			myDlObject.download(url, downloadItemId);
		}
	}));
}

Nun hängt aber mein Hauptprozess, er lädt die erste Datei runter und es gibt auch keine Fortschrittsanzeige mehr (das wohl weil der Hauptprozess hängt).

Ich glaub ich sitz schon wieder zu lang davor.

Gruß

Arno

5.742 Beiträge seit 2007
vor 12 Jahren

Nun hängt aber mein Hauptprozess, er lädt die erste Datei runter und es gibt auch keine Fortschrittsanzeige mehr (das wohl weil der Hauptprozess hängt).

Das ist auch kein Wunder - siehe die Falle in [FAQ] Warum blockiert mein GUI?

A
ArnoNuehm Themenstarter:in
47 Beiträge seit 2010
vor 12 Jahren

Was mache ich nun falsch?

private void downloadStarten_Click(object sender, EventArgs e)
{
	if (listView1.Items.Count > 0)
	{
		Thread thread = new Thread(doDownload);
		thread.Start();
	}
	else MessageBox.Show("Keine Downloads in der Liste !", "Fehler");
}

private void doDownload()
{
	int z = 1;
	while (z <= listView1.Items.Count)
	{
		this.Invoke(new MethodInvoker(downloadWorker));
		z++;
	}
}

private void downloadWorker()
{
	for (int i = 0; i < listView1.Items.Count; i++)
	{
		string downloadName = listView1.Items[i].SubItems[1].Text;
		string url = myObject.getDataLink(downloadName);
		int downloadItemId = i;
		myDlObject.download(url, downloadItemId);
	}
}

Gruß

Arno

U
1.688 Beiträge seit 2007
vor 12 Jahren

Was mache ich nun falsch?

Immer noch das selbe. Du verlagerst die eigentliche Arbeit wieder zurück in den GUI-Thread.

4.928 Beiträge seit 2008
vor 12 Jahren

Hallo Arno,

lies dir einmalig die Download-Liste aus dem ListView aus (z.B. als List<string>) und übergib diese dann der Thread-Methode, welche dann in der Schleife die einzelnen Dateien herunterlädt (ohne Invoke!).

A
ArnoNuehm Themenstarter:in
47 Beiträge seit 2010
vor 12 Jahren

Danke Euch.

Ich habe es eben schon lösen können und poste später mal meinen aktuellen Code dazu.

Gruß

Arno

U
1.688 Beiträge seit 2007
vor 12 Jahren

Hallo,

hilfreich ist für solche Fälle auch noch dies:
SyncQueue <T> - Eine praktische Job-Queue

T
381 Beiträge seit 2009
vor 12 Jahren

Der Punkt ist, dass

this.Invoke(new MethodInvoker(downloadWorker));

die downloadWorker() mehtode im GUI Thread ausführt. Das ist genau der Sinn von Invoke von WinForms.
Schau dir auch mal den "BackgroundWorker" an der für solche Fälle gut geeignet ist.