| 

.NET C# Java Javascript Exception

3
Folgenden Aufbau habe ich im Moment:

Public Class Form1
...
End Form1
Public Class Subs
...
End Subs

In Form1 gibt es jetzt in einer Sub (ein Button) folgende Befehle:

Dim t1 As New Subs
Dim t2 As New Subs
Dim s1 As New Thread(New ParameterizedThreadStart(AddressOf t1.routine))
Dim s2 As New Thread(New ParameterizedThreadStart(AddressOf t2.routine))
s1.Start(New Object() {0, 4})
s2.Start(New Object() {1, 4})

Somit marschieren 2 Threads im Hintergrund fröhlich vor sich hin. Da die Routinen sehr lange laufen, möchte ich jetzt einen Button dazufügen, mit dem ich die beiden Threads wieder stoppen kann - das ist also eine andere Sub. Mit einem

s1.Abort() : t1.Dispose()

in einer anderen Sub kann ich das nicht machen. Und als Public lassen sich die Instanzen auch nicht definieren ("Public ist bei der Deklaration von lokalen Variablen ungültig"). Wie bekomme ich die Threads beim Klick gestoppt?

Besten Dank!
News:
09.08.2011
muffi 1,4k 1 9
2 Antworten
3
Thread.Abort() ist die verkehrte Strategie, um einen Workerthread anzuhalten! Das sollte nur geschehen, wenn es beim Stop der Anwendung nicht anders geht.
Stattdessen ist es besser wenn dein Thread zyklisch ein Abbruchflag prüfen, das von deinem Haupt-Thread aus gesetzt wird.

also sowas in der Art:
void threadmethod()
{
while (!shouldStop)
{
// mache irgendwas
}
}

private void buttonStop_Click(object sender, EventArgs e)
{
shouldStop = true;
}


Das Vorgehen ist also ziemlich einfach, du brauchst dafür keine extra Bibliotheken.
09.08.2011
puls200 3,8k 7
Okay, das mit dem Flag ist eindeutig eine gute Idee - dass ich als Anhänger von globalen Variablen da selber nicht drauf gekommen bin? ;-) Nun, es ist zwar eine monumentale For-Schleife, aber ein Exit For sollte ja klappen. Danke! (Und wenns ohne Probleme klappt, gibts das grüne Hackerl ;-) )
muffi 09.08.2011
1
Kleine Randbemerkung: Auch wenn diese Lösung funktioniert, ist sie m.E. weit weg von einer sauberen Lösung. Der threadübergreifende Zugriff auf eine nicht geschützte Variable suggeriert, als sei das beliebig so machbar.
Die Gefahren des Multithreading (Deadlocks, Race Conditions, ...) sollten durch saubere Synchronisierungskonzepte minimiert werden.
ffordermaier 09.08.2011
Ich lasse insgesamt 4 von den Threads laufen, das marschiert ohne Probleme. Und eine Public, die nur für den Zweck des "Abbruch-Flags" da ist, sehe ich jetzt als nicht ganz so schlimm an. Noch unsauberer ist es, über den Taskmanager das Konstrukt zu beenden...
muffi 09.08.2011
Florian: das stimmt natürlich. Gemeinsame verwendete Variable sollte man natürlich schützen. In diesem Fall kann jedoch aus meiner Sicht darauf verzichtet werden, da das Setzen der Variablen auf true das Abbruchkriterium der Threads ist und nicht weiter verändert wird.
puls200 09.08.2011
Der BackgroundWorker macht es mit IsCancellationPending auch nicht anders.
CodeSniffer 09.08.2011
1
Hallo muffi,

statt Dich LowLevel mit Threads rumzuärgern, würde ich Dir zur Verwendung der TaskParallelLibrary (TPL) raten.
Dort sind genau solche Mechansimen, die Du brauchst, bereits verfügbar. Ein Beispiel, wie die CancellationTokenSource eingesetzt wird, um einen Task zu canceln, findest Du hier.

EDIT:
Für .NET 3.5 und vor dem Hintergrund, dass Du es mit einem Formular zusammen einsetzen willst, kannst Du auch zum BackgroundWorker greifen.

Oder, falls Du die TPL mit 3.5 einsetzen willst, kann man das scheinbar auch nachrüsten (ist wohl bei der 3.5 Version der ReactiveExtensions mit dabei)

Viel Erfolg
Florian
09.08.2011
ffordermaier 8,4k 3 9
Die Antwort hilft mir leider nicht weiter, da ich kein .Net 4 zur Verfügung habe! Ich muss leider mit 3.5 auskommen :-/
muffi 09.08.2011
Ok, hab meinen Beitrag editiert. Vielleicht hilft Dir das weiter.
ffordermaier 09.08.2011

Stelle deine .net-Frage jetzt!