Mein VB.Net 2005 geht mir mit den Warnungen langsam auf den Geist - suspend() und resume() sind obsolet. Ich starte mehrere Threads (IsBackground = False), die Deadlock-sicher sind. Von daher sehe ich keinen Grund, die beiden Kommandos nicht einzusetzen. Auch eine Abbruchbedingung über eine globale Variable habe ich eingebaut. Nur beim Pausieren habe ich gerade so überhaupt keine Ahnung, wie ich das für .Net 3.5 umschreiben soll.
Vielen Dank für (Denk-)Anstöße :-)
Zur Verdeutlichung das Gerüst:
Class Form Dim abbruch as Byte = 0 Dim trd as New Thread (AddressOf machwas)
Sub Starte() trd.start() While (trd.ThreadState = ThreadState.Running) or (trd.ThreadState = ThreadState.Running) Thread.Sleep(2000) 'Macht noch ein bischen was' End While End Sub
Sub warte() trd.Suspend() End Sub
Sub weiter() trd.Resume() End Sub
Sub stop() abbruch = 1 End Sub
Sub machwas() For x as Integer = 0 to 1000 'Arbeit' If abbruch = 1 then Exit For Next End Sub End Class
Du kannst das mit einem ManualResetEvent machen. Beim Start wird es mit
new ManualResetEvent(true);
initialisiert, zum Pausieren rufst Du auf dem Event die Reset()-Methode, zum Weiterlaufen die Set()-Methode, und in der machwas()-Methode in jedem Schleifendurchlauf WaitOne().
Die empfohlene Strategie scheint jetzt zu sein die Threads mit einem Art Mutex anzuhalten (WaitOne). Hier findest du eine längere Diskussion zu dem Thema. Warum die Methoden inzwischen obsolete sind entzieht sich meiner Kenntnis. Gruß Daniel
Das "Warum" steht in der Doku: Sie können nicht feststellen, welchen Code ein Thread zum Zeitpunkt der Unterbrechung ausführt. Wenn ein Thread während der Auswertung von Sicherheitsberechtigungen unterbrochen wird, in der er über Sperren verfügt, kann dies zum Blockieren anderer Threads in der AppDomain führen. Wenn Sie einen Thread unterbrechen, der gerade einen Klassenkonstruktor ausführt, werden andere Threads in der AppDomain blockiert, die die entsprechende Klasse verwenden möchten. Dies kann sehr schnell zu Deadlocks führen.
Hier geht MS einfach auf Nummer sicher. Der Ansatz über WaitOne ist natürlich robuster, macht es aber auch erforderlich, dass entsprechender Code in die betroffenen Threads eingebaut wird. Aus meiner Sicht ist es damit kein Ersatz für obige Funktionen.
Insbesondere der Satz "die Deadlock-sicher sind" kann nicht richtig sein, weil Du nicht sämtlichen laufenden Code kontrollierst. Z.b. weißt Du nicht, was der statische Konstruktor von System.Int32 macht (und auch wenn er leer ist, kann er ein Deadlock produzieren, wenn Suspend() genau dort anhält).
Wenn Du aber bereit bis, das Risiko einzugehen, vllt. weil ein Fehlschlagen oder Freezen deines Prozesses nur geringe Probleme verursacht, kannst Du natürlich mit (public) Reflection die Methode ohne Warnung aufrufen. Ich bin mir nicht sicher, ob Obsolete-Warnungen per #pragma unterdrückt werden können.
Einen Workaround für die Warnung gefunden: im vbproj-File einfach mal nach dem Block <NoWarn> suchen und Nummer 40000 dazu. Dann beschwert sich VB nicht mehr darüber.
Sie können nicht feststellen, welchen Code ein Thread zum Zeitpunkt der Unterbrechung ausführt. Wenn ein Thread während der Auswertung von Sicherheitsberechtigungen unterbrochen wird, in der er über Sperren verfügt, kann dies zum Blockieren anderer Threads in der AppDomain führen. Wenn Sie einen Thread unterbrechen, der gerade einen Klassenkonstruktor ausführt, werden andere Threads in der AppDomain blockiert, die die entsprechende Klasse verwenden möchten. Dies kann sehr schnell zu Deadlocks führen.