Threadhandling .Suspend() <-> .Abort()

iMarcG5

Mitglied
Threadprozess optimierung durch ThreadStates

So guten Tag erstmal euch allen.

Wie ihr schon an der Überschrift erkennen könnt geht es mir um Threadhandling.
Zunächst mal wollte ich loswerden, dass es bei mir alles gut funktioniert.
Zu meinem "Problem" und woran ich arbeite.
Ich schreibe ein Programm , das mit GPS- Daten einer GPS Maus etwas "macht". (sorry , darf es leider nicht näher erläutern!)

Ich habe dazu eine Automatische Erkennung geschrieben, das die ports 1-8 abwechselnd öffnet, den Stream untersucht und wieder schließt.
Wird der GPS- stream erkannt, ist natürlich auch die Maus und ihr Port erkannt.

Dazu benutze ich einen Thread, und eine Switch{}!
Zum ablauf:
Thread wird gestartet. Variable auf "1"
1. Port wird geöffnet.
Thread.Sleep(2000) //damit ein wenig ein Input vorhanden ist
Der eingegangene stream wird untersucht. falls nix war, wird variable erhöht und dann der 2. Port usw untersucht. Wird der Port gefunden, ist es ja abgeschlossen.
Da ich einen Thread, der mit "Abort()" beendet wurde nicht mehr öffnen kann, benutze ich Thread.Suspend()

will ich die Autoerkennung wieder ausführen, wird der Thread nat. nicht neu gestartet sondern "Resume()d". Was auch alles eins A funktioniert.

Nun aber zu dem was mich stört.
Der Thread wird ja mit Thread.Suspend(); angehalten (in der Theorie). Bei mir braucht jedoch genau dieser Thread wenn er ThreadState = "Suspended" ist 100% CPU !!

Und das geht ja mal gar nicht klar!

Es scheint als hätte ich da was falsch verstanden. Aber das kann ja wirklich nicht sein.
Zudem verwundert mich eben, dass man es ja so machen MUSS, wenn man den Thread anhalten und wieder starten will. Also kann das ja eigentlich schon gleich zweimal nicht sein!

Ich hoffe ihr habt verstanden worum es mir geht und könnt mir helfen.

PS: ich hoff ich war zur abwechslung mal nettiquette - Konform :)
 
Zuletzt bearbeitet:
Dass es kaum zu verstehen ist, dass das mit den Threads so läuft . Vor allem das mit der Prozessorauslastung ist ja klar. Aber dass mir da wirklich gar niemand weiterhelfen kann

Wäre wirklich nett wenn ihr mal eure erfahrungen bzgl. Threads und den versch. Thread-States posten würdet und maybe auch Ideen woran es bei mir liegen könnte.

Was mir nicht runtergeht ist, wofür gibt es .Suspend(); wenn ich ihn stattdessen auch weiterlaufen lassen könnte. Braucht ja gleich viel CPU... das ist für mich nicht logisch!

Genauso , was mir aufgefallen ist, ist dass Threads im ThreadState "Suspended" nicht mirt Abort(); geschlossen werden können.


Also. auch falls mir niemand helfen kann (was ich mir bei den schlauen Leuten hier kaum vorstellen kann ... Alex, Norbert, der "Cosmo-Chaoschaot" ;) etc)
wäre es doch nicht schlecht hier so eine kleine "Thread... How To " Diskussion zu schreiben, die nacher auch Anderen hilft.
Also einfach Erfahrungen posten die eben nicht in der MSDN stehen.

Vielen Dank!

Gruß Marc
 
Zuletzt bearbeitet:
Hast schon mal versucht deine Logik aus dem Thread rauszunehmen und dann zu starten, zu pausieren und wieder zu starten? Also ein Thread der eigentlich gar nichts tut.

Wenn dann das Problem nicht auftritt, dann hats was mit deiner Implementierung. Normalerweise ist es so, dass bei Netzwerkverbindungen etc. weitere Threads konsultiert werden. Eventuell blockiert dir davon einer eine Ressource, quasi ein Deadlock. Check das mal ab.
 
Hallo Norbert Eder,
danke für den Tip, leider hab ich das ganze schon versucht.
Ich habe schon einen verdacht woran es liegt, mein Problem ist nur, dass ich mir nicht anders vorstellen kann (im Moment) wie ich sonst die Funktionalität aufrecht6 halten kann.
Ich will die Funktion der Klasse etwas genauer beschreiben.

Es gibt 2 Threads und 3 Methoden

1. Methode:

Code:
Port_DataRecieved ()
    {
     diese Methode nimmt den Stream vom Port auf und schreibt den input-Buffer Stream in die Variable "stream"
    }


2. Methode + 1. Thread
Diese Methode wird vom Thread (PortDetectionThread) aufgerufen:
Code:
   PortDetection()
   {
   while(true)
     {
      hier wird nacheinander ein Port nach dem anderen geöffnet und gewartet bis Daten geflossen sein können.
   
   switch(Portnummer)
    case 0:
   
   port.close() // provisorisch mal schließen
   port.open(Portnummer+1) // Port 1 öffnen
   Portnummer++;
   Thread.Sleep(2000);
   
   break;
   
   
   case 1:
   
   if(InputBuffer == 0) // keine Daten erhalten
   {
  /*falls keine Daten angekommen sind, ist der Port falsch. Dasselbe wie vorher wird gemacht. Nächster Port wird geöffnet.*/
   port.close() // schließen
    port.open(Portnummer+1) // Port 1 öffnen
    Portnummer++;
    Thread.Sleep(2000);
   break;
   }
   else
   {
    port_DataRecieved(); // falls Daten angekommen sind, wird Die DataRecieved Methode aufgerufen, die den Buffer ausließt
  
    Portnummer++;
   break;
   }
   
   case
   .
   .
   .
   und so weiter, bis alle Prots durchgemacht sind, oder bei etwas angekommen ist. somit kommen wir zur letzten Methode:
   
   
     }
   }

3.Methode + 2. Thread
Die Methode IncomingCheck wird vom IncomingCheckThread aufgerufen.

Code:
IncomingCheck()
   {
   while(true)
   {
   if(stream.Substring(0,5) == GP...) //wenn eben der stream ein bestimmterStream der GPS maus ist
   {
   MessageBox.show("Port wurde gefunden" + Portnummer);
   und hier werden nun beide Threads pausiert mit:
   IncomingCheckThread.suspend();
   PortDetectionThread.Suspend();
   
   hier kann das Problem liegen, ich hab aber klein blassen wieso er da meckert!!
   
   }
    }Thread.Sleep(500);
   }

Ich hoffe ich habe mein vorgehen verständlich erklärt.
Ich hab schon alles versucht... Events... aber nur mit den Threads hat die Automatische Erkennung richtig funktioniert.
Leider habe ich wie gesagt dieses "Suspend" - Problem.

Vielleicht wird für Dich oder jemand anderes dadurch jetzt mein Fehler ersichtlich... weil ich vielleicht den Thread aus der Methode pausiere, die ich vom Thread aufrufe.

HM... ich weiß da net genau weiter.

Vielen dank auf jeden Fall mal
 
Zuletzt bearbeitet:
Dein IncomingThread ... wie wird der gestartet? Könntest den Ablauf kurz skizzieren. Ich glaube nämlich dass beide Threads auf die gleichen Ressourcen zugreifen und durch das suspenden des einen Threads läuft der andere natürlich über. Auf jeden Fall versteh ich nicht ganz warum du da zwei Threads hast.

Bedenke übrigens auch, dass ein Event welches von einem Thread geworfen wird, auch unter diesem Thread läuft ..
 
Hallo iMarcG5!

Erstmal eines vorweg,
ich bin kein "Chaos-Chaot", ich bin der CHAOSMAKER.
Kannst nich aber auch einfach cosmo nennen. ;)

Bin der selben Meinung wie Norbert.
Mal ne frage zu dem switch Konstukt?
Wird nicht bei allen Ports das gleiche gemacht?
Würde sich nicht eine Funktion mit dem Port parameter eher anbieten?
Kann mich aber auch irren.

Desweiteren empfehle ich Dir auch Events zu verwenden
und auf den anderen Threads zu Invoken.

Wie währe es wenn Du den Threads signalisierst das sie vonn allein halten sollen
wenn sie die Ressurce nicht mehr verwenden?
In dem Post siehst den Ansatz einer Möglichkeit.
[thread=210935]Thread Hilfe, wie beenden? - Thread[/thread]

Oder schau Dir mal das WorkerThreadStarter Kit an:
[thread=199136]Threading hilfe - Thread[/thread]

//Edit: Ich finde auch das Du erstmal alles
über einen einzigen Thread regeln kannst.
Dann kannst im nachhinein das Phenomen ergründen und hast erstmal ein Ergebnis. :)

MfG, cosmo
 
Zuletzt bearbeitet:
Zunächst mal danke über die Antworten:
zu Norbert:
Ablauf:
Ich starte das Programm und sobald ein warnhinweis mit OK- bestätigt wird, öffnet sich mein "Hauptmenü" beim Button_Click wird auch gleichzeitig meine PortDetection Klasse aufgerufen.


(kurz zum Aufbau... ich habe aufgrund der Anforderungen mein Programm etwas komisch aufgebaut... also alle OOP Checker, nicht erschrecken. Es gibt eine MainClass, die alle objekte anlegt. über diese MainClass können viele public (nicht hauen bitte) Methodern / Variablen von überallher verwendet werden. soviel Dazu! )

mit: "Namespace".MainClass.portDet.detectPort(true); wird die Methode in der PortDetection Klasse aufgerufen! das true ist mal unwichtig.(zeigt von wo aus , Anfang oder Settings die Detection gestartet wurde!)
In dieser Methode werden die Threads gestartet. (alles was ich oben beschrieben habe läuft auch in dieser PortDetection Class ab! die Switch...alles)

zu Norbert und Cosmo
Warum ich 2 Threads verwende.
1. ganz einfach... das eine wird nur alle 2 sec das andere alle 0.5 sec weiderholt. (ok... schlechtes argument ;) ) zudem nur, wenn ein bestimmter Weg bei den 2 sec eingeschlagen wird. (InputBuffer != "")
somit wird es nicht ganz einfach!

zudem glaube ich nicht dass es mein Problem lößt, da ich trotzdem noch den Thread aus der Methode pausiere, die von diesem Thread aufgerufen wird... ich denke Daran liegt das Problem. Ich weiß es allerdings nicht wirklich!

PS: das mit dem überlaufen sagt mir noch nicht wirklich was, im zusammenhang wenn beide auf die selben ressourcen zugreifen.
Was genau sollich mir darunter vorstellen. vielleicht komm ich dann ja selbst auf die Lösung.. meinst du speicherbereiche, oder dass er durch das Suspenden des einen das Suspenden des anderen verhindert

wahrscheinlich läuft es nacher drauf raus, dass ich nur die Zwei Zeilen in der reihenfolge vertauschen muss und dann gehts ;) ... gleich mal versuchen !!:)

bis Später!

Gruß Marc

[UPDATE]

Die Reihenfolge hat gestimmt... andersrum hat es gar nicht mehr funktioniert;)
 
Zuletzt bearbeitet:
Mach mal ein lock( MySyncRootObj ) vor zugriff auf den Port in der Methode Port_DataRecieved() rein.
Genau so auch bei der Methode IncomingCheck().
Damit solltest den doppelten zugriff erstmal unterbinden können.

Schreib doch einfach mal in die Trace jeden einzelnen Schritt rein
wenn Du den DeathLock nicht findest (ich mein nach jeder einzelnen Zeile),
da siehst dann ab wann alles hängt.

(kurz zum Aufbau... ich habe aufgrund der Anforderungen mein Programm etwas komisch aufgebaut... also alle OOP Checker, nicht erschrecken. Es gibt eine MainClass, die alle objekte anlegt. über diese MainClass können viele public (nicht hauen bitte) Methodern / Variablen von überallher verwendet werden. soviel Dazu! )
Was für ein Chaos, :rolleyes:
Von Threads aus kannst aber nichts einfach so auf alles zugreifen.
Ganz besonders nicht auf Controls ect. Da musst Du mit delegates arbeiten.
Deswegen können wir, denke ich mal, keine besseren Tipps geben,
da Du ja schon gesagt hast, das Du den kompletten Code miteinander verwurschtelt hast.
Und sich dadurch alles anders verhält, sprich Zugriffsprobleme vorprogrammiert sind.
 
Zurück