Entwickler-Ecke
Basistechnologien - Methoden als eigenen Thread mit Timeout starten
Laurence - Mi 10.02.10 10:02
Titel: Methoden als eigenen Thread mit Timeout starten
Hallo und guten morgen ihr alle da draußen!
Ich hab ein Problem, bzw. mehrere Probleme. Ich möchte was mit Threads lösen, weiß aber nicht wie!
Und zwar habe ich eine Liste von Objekten, wo jedes mal die Methode perform ausgeführt werden soll.
Bis dahin funktioniert auch alles.
Nun möchte ich jedoch, falls die Methode zu lange läuft, dass sie
abgebrochen wird, wie z.B. kopieren von großen Ordnern über ein langsames Netzwerk (Timeout).
Ich habe mir gedacht, dass ich das als Thread löse, jedoch habe ich davon leider keine Ahnung! :-(
Habe den etwas vereinfachten Quelltext wie es momentan ist, unten.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| public class Example { public List<Worker> Workers = new List<Worker>(); public bool Execute() { bool OperationSuccessful = true; foreach (Worker wo in Workers) { if (wo.perform() == false) { OperationSuccessful = false; } else { } } } |
Hatte es mal mit Threads probiert, jedoch muss der Returnwert anscheinend VOID sein.
C#-Quelltext
1:
| Thread mythread = new Thread(this.Workers[0]perform); |
Vielen Dank für eure Hilfe
Gruß Laurence
JüTho - Mi 10.02.10 10:17
Hallo,
mein Vorschlag ist, dass du dich zunächst um einen Thread kümmerst, damit du die Zusammenarbeit zwischen Programm und getrennten Threads kennenlernst. Noch besser gefällt mir der BackgroundWorker, weil der die wichtigsten Schritte kapselt und deshalb einfacher zu bedienen ist. Ein schönes Beispiel ist in der SDK-Doku/MSDN/Hilfe zu finden.
Wenn das erledigt ist, sollte es kein Problem sein, mehrere solcher Threads bzw. worker zusammenzufassen.
Gruß Jürgen
danielf - Mi 10.02.10 10:57
Hallo,
einen TimeOut kannst du so realisieren, dass die Methode parallel startest aber dann wiederum auf sie wartest (joinst). Die join-Methode hat einen Parameter TimeOut. Wenn dieser Abgelaufen ist oder die Methode zu ende ist wird dein Code fortgesetzt. Da musst du dann unterscheiden ob der Thread beendet wurde oder der TimeOut erreicht wurde und dementsprechend reagieren.
Gruß Daniel
Edit: Googel findet folgendes
Link [
http://dotnet-snippets.de/dns/die-ausfuehrungszeit-einer-methode-einschraenken-SID723.aspx].
Laurence - Mi 10.02.10 11:23
danielf: Also dieses Beispiel habe ich auch schon gefunden und versucht einzubinden.
Jedoch bekomme ich bei folgendem Aufruf...
C#-Quelltext
1: 2: 3:
| TimeOut to = new TimeOut(); if (!to.DoIt(new RunMethodDelegate(wo.perform()), TimeSpan.FromSeconds(2))) {...} |
...die Fehlermeldung:
bool Worker.perform()' has the wrong return type
Was mach ich falsch, oder wie gehts richtig?
Danke
danielf - Mi 10.02.10 11:37
Die RunMethodDelegate erwartet keinen Wert sondern einen "Funktionspointer". D.h. lass die Klammern weg, dann sollte es gehen.
Laurence - Mi 10.02.10 11:40
danielf hat folgendes geschrieben : |
| Die RunMethodDelegate erwartet keinen Wert sondern einen "Funktionspointer". D.h. lass die Klammern weg, dann sollte es gehen. |
Oh sorry, das war mein Fehler, die Klammer gehört nicht hin
C#-Quelltext
1: 2: 3:
| TimeOut to = new TimeOut(); if (!to.DoIt(new RunMethodDelegate(wo.perform), TimeSpan.FromSeconds(2))) {...} |
danielf - Mi 10.02.10 11:55
Hmm.. beim genaueren betrachten ist der Code nicht mehr einleuchtend :)
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Program p = new Program(); Thread t = new Thread(new ParameterizedThreadStart(p.DoSomething));
t.Start();
t.Join(TimeSpan.FromSeconds(2));
if (t.ThreadState != System.Threading.ThreadState.Stopped) { MessageBox.Show("TimeOut!"); t.Abort(); } |
So finde ich es eigentlich logischer.
Laurence - Mi 10.02.10 12:12
Ja ist es auf jeden Fall!
Bis dahin war ich auch schon mal vor ewigen Zeiten gekommen, bis mich dann der Fehler
No overload for 'perform' matches delegate 'System.Threading.ParameterizedThreadStart'
abgeschreckt hatte. Hattes es daraufhin mit dem BackgroundWorker und dieser tollen Klasse probiert.
danielf - Mi 10.02.10 12:14
Aber nun gehts? Oder fehlt dir noch was?
Du solltest alle Bauteile haben.
Laurence - Mi 10.02.10 12:33
Nene, geht nun, siehe:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7:
| Thread t = new Thread(new ParameterizedThreadStart(delegate { act.perform(); })); t.Start(); t.Join(TimeSpan.FromSeconds(2)); if (t.ThreadState != System.Threading.ThreadState.Stopped) { MessageBox.Show("TimeOut!"); t.Abort(); } |
Nur leider klappt das t.Abort() nicht, bzw. es klappt bestimmt schon, nur bei meiner Methode nicht
danielf - Mi 10.02.10 12:35
Das t.Abort löst in dem Thread ein Exception aus (ThreadAbortException). Wenn du diese (oder generell Exception) in deiner Methode abfängst dann bleibt der Thread aktiv.
Laurence - Mi 10.02.10 14:04
hat nun funktioniert, das Exception Handling hatte nur irgendwie so gut gegriffen! :-)
danielf - Mi 10.02.10 14:06
Das bezweifle ich, wenn es alles gleich behandelt ;)
Deshalb immer spezifische Exceptions schmeißen. Dann macht das Fehlerhandling auch "Spaß" und es tut wie es soll ;)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!