myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » Blockierte Threads sicher beenden
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Blockierte Threads sicher beenden

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Ishildur Ishildur ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.09.2005
Beiträge: 431
Entwicklungsumgebung: Visual c# .NET
Herkunft: Schweiz


Ishildur ist offline

Blockierte Threads sicher beenden

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo zusammen
Ich bin relativ neu in der Entwicklung von parallelen Anwendungen und habe hierzu mal eine ganz Grundlegende Frage, welche viele meiner gegenwärtigen Probleme lösen könnte:

Ich beschäftige mich gerade mit dem Problem, wie man Threads "sicher" beenden kann. Normalerweise habe ich eine bool'sche volatile Variable welche ich im Workerthread an verschiedenen Prüfe und gegenenfalls den Thread von innen heraus beende, indem ich bspw. mit break aus einer Schleife springe oder so ähnlich. Mit dieser Technik habe ich bisher sehr gute Erfahrungen gemacht, doch gibt es Fälle, wo der gesamte Thread auschliesslich eine blocking methode enthält. Ein Beispiel hierfür wäre Socket.Accept. Hier kann ich nicht eifach ein Flag prüfen, denn sobald ich Socket.Accept aufgerufen habe, geht der Programmfluss in diesem Thread nicht weiter, bis ein engehende Verbindung zustande gekommen ist. Aber bei Socket.Connect dauert es dann bis zu 30 sekunden, bis der entsprechende Thread dann auch wirklich schliesst.

Meine Frage ist nun, wie kann ich solche Threads "sicher" beenden (das heisst, sicherstellen, dass alle Resourcen freigegeben werden) ? Thread.Abort soll ja keine gute Variante sein, weil sich der ensprechende Thread zum gegebenen Zeitpunkt im finalize block befinden könnte, wodurch dieser dann nicht bis zum Ende ausgeführt wird...

Mfg Samuel
Neuer Beitrag 31.03.2009 12:26 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
marsgk marsgk ist männlich
myCSharp.de-Mitglied

Dabei seit: 04.06.2005
Beiträge: 1.439
Entwicklungsumgebung: Notepad++ + csc + nmake
Herkunft: Linz, Austria


marsgk ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

=>Thread.Interrupt()
Neuer Beitrag 31.03.2009 12:56 Beiträge des Benutzers | zu Buddylist hinzufügen
Ishildur Ishildur ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.09.2005
Beiträge: 431
Entwicklungsumgebung: Visual c# .NET
Herkunft: Schweiz

Themenstarter Thema begonnen von Ishildur

Ishildur ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das verstehe ich jetzt nicht:
In der offiziellen Doku steht dazu folgendes:

Zitat:
ThreadInterruptedException wird im unterbrochenen Thread ausgelöst, jedoch erst, nachdem der Thread blockiert wurde. Wenn der Thread nie blockiert wird, wird die Ausnahme nicht ausgelöst. Daher kann der Thread möglicherweise ohne Unterbrechung abgeschlossen werden.

Also wenn ich das richtig verstehe, kann ich damit einen laufenden Thread nicht unterbrechen?

Abgesehen davon, selbst wenn es funktionieren würde, dann hätte ich doch dasselbe Problem wie bei Thread.Abort()?

Bei Thread.Abort() wird im entsprechenden Thread ThreadAbortedException und bei Thread.Interrupt() ThreadInterruptedException ausgelöst. Beides wird allerdings nicht funktionieren, wenn sich jener Thread gerade im finalize block befindet?
Neuer Beitrag 31.03.2009 13:02 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Corpsegrinder
myCSharp.de-Mitglied

Dabei seit: 30.01.2007
Beiträge: 401
Entwicklungsumgebung: VS 2008 , .Net 3.5


Corpsegrinder ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Du kannst den Socket einfach mit Socket.Close() schließen und die auftretende Exception fangen und entsprechend behandeln.
Neuer Beitrag 31.03.2009 13:07 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Ishildur Ishildur ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.09.2005
Beiträge: 431
Entwicklungsumgebung: Visual c# .NET
Herkunft: Schweiz

Themenstarter Thema begonnen von Ishildur

Ishildur ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hehe, du meinst, ich sollte den Socket im Aufrufenden Thread schliessen (nicht im Workerthread, welche Socket.Accept aufruft und anschliessend am warten ist?
Neuer Beitrag 31.03.2009 13:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
kleines_eichhoernchen kleines_eichhoernchen ist männlich
myCSharp.de-Mitglied

avatar-2079.jpg


Dabei seit: 07.11.2006
Beiträge: 3.971
Entwicklungsumgebung: Visual Studio 2005 (C#)
Herkunft: Ursprünglich Vogtland, jetzt Much


kleines_eichhoernchen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ein Thread sollte sich im normal-Fall immer selbst beenden. Beispielsweise über eine boolsche Variable, die in einer Schleife geprüft wird.

Um Threads zu killen, empfiehlt es sich Thread.Abort zu verwenden. Ein Zwischending zwischen (sauber) beenden und killen gibt es nicht.

Weiterhin gibt es im .NET Framework viele Klassen, die nach dem Asynchronen Enwturfsmuster von Microsoft gehalten sind. Dort hast du entweder BeginXYZ sowie ein passendes Pendant dazu (EndXYZ) oder aber es werden dir diverse Events angeboten, die automatisch gerufen werden, wenn ein bestimmtes Ereignis eintritt (Client verbindet sich mit Socket).

Die Klasse Socket enthät beispielsweise eine Funktion BeginAccept, die ein CallBack (Delegate/Event) erwartet, das autoamtisch gerufen wird, sobald sich ein Client mit dem Socket verbunden hat. Die Funktion die BeginAccept aufgerufen hat, setzt seine arbeitet ohne warten fort.

Die Funktion EndXYZ wartet solange (hält den aktuellen Thread an), bis die Funktion BeginXYZ mit ihrer Arbeit fertig ist.

Wichtig, bei BeginXYZ, immer auch EndXYZ aufrufen. MS merkt sich, die noch offenen BeginXYZ aufrufe. Bei Anwendungen mit langer Lebensdauer, könnte das zu einem Speicherleck führen.

Das ganze nochmal zum Nachlesen/vertiefen:
 Entwurfsmuster für die asynchrone Programmierung
Neuer Beitrag 31.03.2009 13:11 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Corpsegrinder
myCSharp.de-Mitglied

Dabei seit: 30.01.2007
Beiträge: 401
Entwicklungsumgebung: VS 2008 , .Net 3.5


Corpsegrinder ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von Ishildur:
Hehe, du meinst, ich sollte den Socket im Aufrufenden Thread schliessen (nicht im Workerthread, welche Socket.Accept aufruft und anschliessend am warten ist?

Nein, du sollst Socket.Close() vom Main Thread aus aufrufen, der Socket wird geschlossen, im Listener Thread wird ne Exception geworfen, weil er nicht auf nem geschlossenen Socket arbeiten kann und der Thread wird nach dem behandeln der Exception Ordnungsgemäß geschlossen.


Edith meint: Wer lesen kann ist im Vorteil :-) Hattest das ja schon richtig geschrieben... Man sollte eben nicht gleichzeitig im Forum schreiben und nebenbei versuchen dem Prof zuzuhören :D

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Corpsegrinder am 31.03.2009 13:20.

Neuer Beitrag 31.03.2009 13:15 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Ishildur Ishildur ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.09.2005
Beiträge: 431
Entwicklungsumgebung: Visual c# .NET
Herkunft: Schweiz

Themenstarter Thema begonnen von Ishildur

Ishildur ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hehe :-) Sitzt du auch gerade in einer Vorlesung? großes Grinsen
Neuer Beitrag 31.03.2009 13:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Corpsegrinder
myCSharp.de-Mitglied

Dabei seit: 30.01.2007
Beiträge: 401
Entwicklungsumgebung: VS 2008 , .Net 3.5


Corpsegrinder ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von Ishildur:
Hehe :-) Sitzt du auch gerade in einer Vorlesung? :D

Jo, Datenbanken....
Neuer Beitrag 31.03.2009 13:35 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Ishildur Ishildur ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.09.2005
Beiträge: 431
Entwicklungsumgebung: Visual c# .NET
Herkunft: Schweiz

Themenstarter Thema begonnen von Ishildur

Ishildur ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Bei mir ists Stochastik Zunge raus
Neuer Beitrag 31.03.2009 13:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Ishildur Ishildur ist männlich
myCSharp.de-Mitglied

Dabei seit: 15.09.2005
Beiträge: 431
Entwicklungsumgebung: Visual c# .NET
Herkunft: Schweiz

Themenstarter Thema begonnen von Ishildur

Ishildur ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

@marsgk
Es scheint so, als ob Thread.Interrupt() in diesem Fall nicht funktionieren würde. Kann es sein, dass Socket.Accept nicht interruptable ist?
Neuer Beitrag 01.04.2009 02:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
kleines_eichhoernchen kleines_eichhoernchen ist männlich
myCSharp.de-Mitglied

avatar-2079.jpg


Dabei seit: 07.11.2006
Beiträge: 3.971
Entwicklungsumgebung: Visual Studio 2005 (C#)
Herkunft: Ursprünglich Vogtland, jetzt Much


kleines_eichhoernchen ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Kann es sein, dass Socket.Accept nicht interruptable ist?

Jupp, weil Accept solange wartet, bis sich ein Client verbindet. Die Socket-Klasse arbeitet intern mit unmanged Code, daher funktioniert Thread.Abort oder Thread.Interrupt nicht. Ein Thread.Abort oder Interrupt wird von der CLR erst verarbeitet, wenn der Thread wieder in managed Code ist.

Der Holzhammer funktioniert eben nicht immer. Deshalb gibts aber die Funktionen BeginXYZ und EndXYZ - in diesem Fall BeginAccept und EndAccept. Dort treten die Probleme nicht auf.
Neuer Beitrag 01.04.2009 07:43 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 10 Jahre.
Der letzte Beitrag ist älter als 10 Jahre.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 11.11.2019 21:22