Re: Threads und BackgroundWorker
Das ist ein Argument. So funktioniert es:
Code:
Und wie breche ich einen mit der Thread-Klasse erstellten Thread ab? Abort löst eine Exception aus und Suspend lässt ihn nur pausieren. Irgendwie fehlt eine Methode zum terminieren.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{ for (int i = 0; i < 100000; i++) { if (backgroundWorker1.CancellationPending) { e.Cancel = true; } else { backgroundWorker1.ReportProgress((int)i / 10); Thread.Sleep(0); } } } |
Re: Threads und BackgroundWorker
Zitat:
Zitat:
PS: Der Thread ist danach allerdings nicht mehr nutzbar und man benötigt einen neuen. Wenn das öfter geschehen soll, sollte man wohl besser einen ThreadPool-Thread benutzen und in diesem (wie in deinem BackgroundWorker-Code) ein Abbruch-Flag auswerten. |
Re: Threads und BackgroundWorker
Gut, dann ist Abort doch richtig.
allerdinsg scheint nichts zu passieren:
Code:
Laut Beispiel aus der Hilfe, müsste es aber so aussehen.
private void btnStop_Click(object sender, EventArgs e)
{ if (rbThread.Checked) { t.Abort(); } else { backgroundWorker1.CancelAsync(); } } private void thread1_Event(object sender, EventArgs e) { try { if (InvokeRequired) { Invoke(new EventHandler(thread1_Event)); } else { for (int i = 0; i < 100000; i++) { lblStatusText.Text = resManager.GetString("ThreadStatusRunning"); this.Update(); Thread.Sleep(0); } } } catch (ThreadAbortException tae) { lblStatusText.Text = resManager.GetString("ThreadStatusFinish"); this.Update(); } } private void ThreadProc() { try { thread1_Event(this, null); } catch (ThreadAbortException tae) { lblStatusText.Text = resManager.GetString("ThreadStatusFinish"); this.Update(); } } |
Re: Threads und BackgroundWorker
Habe ich irgendwo oben schon zu deinem ersten Thread-Code geschrieben: Du invokst thread1_Event, also wird deine gesamte Schleife im Hauptthread ausgeführt und dort kann Abort schlecht wirken. Es wird warten, bis thread1_Event beendet ist und erst dann die Exception werfen.
|
Re: Threads und BackgroundWorker
Zitat:
Code:
private void button1_Click(object sender, EventArgs e)
{ if (rbThread.Checked) { try { t = new Thread(ThreadProc); t.Name = "Thead"; t.Start(); } catch { } } else { backgroundWorker1.RunWorkerAsync(); } } private void btnStop_Click(object sender, EventArgs e) { if (rbThread.Checked) { t.Abort(); } else { backgroundWorker1.CancelAsync(); } } private void thread1_Event(object sender, EventArgs e) { try { if (InvokeRequired) { Invoke(new EventHandler(thread1_Event)); } else { for (int i = 0; i < 100000; i++) { lblStatusText.Text = resManager.GetString("ThreadStatusRunning"); this.Update(); Thread.Sleep(0); } } } catch (ThreadAbortException tae) { lblStatusText.Text = resManager.GetString("ThreadStatusFinish"); this.Update(); } } private void ThreadProc() { try { thread1_Event(this, null); } catch (ThreadAbortException tae) { lblStatusText.Text = resManager.GetString("ThreadStatusFinish"); this.Update(); } } |
Re: Threads und BackgroundWorker
Zitat:
Code:
Edit: Nach dem dritten Edit übernehme ich lieber keine Verantwortung über die Richtigkeit des Codes ;) .
void thread1_Event()
{ lblStatusText.Text = resManager.GetString("ThreadStatusRunning"); this.Update(); Thread.Sleep(0); } void ThreadProc() { try { for (int i = 0; i < 100000; i++) { Invoke(new MethodInvoker(thread1_Event)); // ich kann durchaus verstehen, dass nicht jeder anonyme Methoden mag *g* } } catch (ThreadAbortException tae) // hier würde ich eher finally benutzen { lblStatusText.Text = resManager.GetString("ThreadStatusFinish"); // und hier sollte es eine Cross-Call-Exception hageln this.Update(); } } |
Re: Threads und BackgroundWorker
Jetzt schlägt allerdings die Aktualisierung im finally-Abschnitt fehl:
Zitat:
|
Re: Threads und BackgroundWorker
Zitat:
Du stellst dich auch manchmal an... ;-) Übrigens musst du nicht so umständlich mit ResourceManagern arbeiten. Das VS erzeugt autom. statische Eigenschaften für jeden Wert in der Resource Datei, so dass du direkt auf den Namen mit dem richtigen Typ zugreifen kannst. |
Re: Threads und BackgroundWorker
Ich verzweifele noch mal an diesen delegate und Invoke.
Code:
Will er auch nicht:
private void SetStatusText(string Text)
{ lblStatusText.Text = Text; this.Update(); } void ThreadProc() { try { for (int i = 0; i < 100000; i++) { Invoke(new MethodInvoker(thread_Event)); Thread.Sleep(0); } } finally { Invoke(SetStatusText(resManager.GetString("ThreadStatusFinish"))); } } Zitat:
|
Re: Threads und BackgroundWorker
Das Problem ist, dass SetStatusText(resManager.GetString("ThreadStatusFi nish")) kein Delegat ist. Bei deinem anderen Invoke-Aufruf hast du das ja auch zuerst in den MethodInvoker-delegaten verpackt.
Du wirst dir also wahrscheinlich für deine SetStatusText(string) einen delegaten basteln müssen, dann die Funktion darin verpacken und dann gehts. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz