Ich möchte praktisch dass Thread1 die höchste Priorität hat, und ich ihn jederzeit starten kann (ohne warten zu müssen) die anderen Threads müssen dann solange warten bis Thread1 fertig ist
Man kann ja jetzt einfach die anderen Task auf suspend stellen, aber dass ist ja auch nicht das ware, weil ich dann später z.b. 11 oder noch mehr Threads habe...
private void AddText(string text)
{
// InvokeRequired required compares the thread ID of the
// calling thread to the thread ID of the creating thread.
// If these threads are different, it returns true.
if (this.listBox1.InvokeRequired)
{
AddTextCallback d = new AddTextCallback(AddText);
this.BeginInvoke(d, new object[] { text });
//this.Invoke(d, new object[] { text });
}
else
{
this.listBox1.Items.Add(text);
}
}
so sieht es schon besser aus, aber dennoch springt manchmal Thread2 rein
eine höhere Priorität verhindert nicht, dass Prozesse/Threads mit geringerer Priorität auch ab und zu mal drankommen. Sonst würde ein Prozess mit hoher Priorität das ganze System lahmlegen. Ist also alles ok.
Wozu überhaupt Threads wenn die Aktionen hintereinander ausgeführt werden sollen? Wenns darum geht das z.B. die GUI nicht blockieren soll, dann ists doch einfacher nur einen Thread zu starten und dort halt die Aktionen hintereinander auszuführen.
wenn du willst, dass Threads bestimmte Aktionen nicht gleichzeitig machen, musst du sie synchronisieren. Das ist ein Thema für sich und da kommt man nicht drum rum sich gründlich einzuarbeiten. Suspend und Resume wären ein schlechtes Mittel, zumal diese Methoden depricated sind. Normalerweise wird mal lock verwenden. Man kann aber auch AutoResetEvent o.ä. verwenden, je nach den konkreten Anforderungen.
Wenn du aber nur willst, dass deine Aufgaben nacheinander abgearbeitet werden, dann pack sie doch einfach in einen Thread. :-)
Lock dient doch dazu, damit die Threads einen Code-Abschnitt nicht gleichzeitig ausführen oder?
Ich kann es nicht in einen Thread packen, da das ganze über einen(bzw. mehrere) Event (Interrupt von einer I/O-Karte) gesteuert wird, und bei einem bestimmten Event muss ich was höher prioritäres (sagt man es so ) erledigen.
Windows ist eh kein Echtzeit-Betriebssystem. Wenn du was höher priorisiertes tun willst, dann setzte die Priorität hoch. Vermeiden, dass Windows statt deiner wichtigen Aufgaben lieber was anderes tut, kannst du eh nicht.
Zur Klärung:
Windows verteilt Prozessorzeit mittels preemptiven Multitaskings. Das bedeutet, jeder Thread bekommt einen Zeitrahmen (Standard: 50ms), ist dieser beendet, wird der Thread angehalten und der nächste wiederaufgenommen.
Ein Thread kann drei schedulerrelevante Status haben: Running, Ready To Run oder Waiting.
Es gibt pro Prozessor nur einen Thread mit dem Status "Running". Dies ist der gerade ausgeführte. Wenn der nächste zum Zuge kommen soll, sucht der Scheduler nach Threads mit dem Status "Ready To Run" und führt denjenigen mit der höchsten Priorität aus (Status wird zu "Running"). Ist der Zeitrahmen vorbei (bzw. wird beendet), wird dieser Thread auf den Status "Ready To Run" gestellt und ein Flag gesetzt, dass er in diesem Durchlauf bereits lief.
Gibt es mehrere Threads mit gleicher Priorität wird derjenige ausgeführt, der noch kein gesetztes Flag hat. Gibt es einen solchen nicht, wird das Flag bei allen wieder entfernt.
Der Status "Waiting" wird durch bestimmte Systemfunktionen vergeben, die größtenteils ein Wait im Namen tragen. Oder auch durch Control.Invoke. Er besagt, dass der Thread zwar noch läuft, momentan jedoch nicht ausgeführt werden braucht, da er auf den Abschluß einer Aktion wartet.
Damit ist klar, warum so eine scheinbar merkwürdige Reihenfolge herauskommt.
Alle Threads beenden ihren Zeitrahmen beim Aufruf von Control.Invoke. Da sie die gleiche Priorität haben, werden sie reihum ausgeführt.
Haben sie jetzt unterschiedliche Prioritäten, so kommen die niedriger priorisierten nur dann zum Zuge, wenn alle höheren nichts zu tun haben.
Allerdings kann das Laufzeitverhalten jetzt nicht mehr vorhergesagt werden, da ja nicht genau bekannt ist, wann die per Control.Invoke in einem anderen Thread gestartetet Methode beendet ist und der Thread wieder zu "Ready To Run" zurückkehrt. In genau diesen Zeiten kommt ein niedriger priorisierter Thread zum Zug, auch er bleibt beim Control.Invoke hängen und macht "Platz" für den nächsten.
Da es jetzt aber noch ganz viele andere Threads anderer Prozesse auf dem System gibt, ist das wirkliche Verhalten noch viel komplexer.
die Prioritäten sind doch da um diese zu nutzen, warum also nicht??
Tja, weil´s halt nicht deterministisch ist - s.o.
In einer komplexeren Applikation (= viele Threads) können hoch-priore Threads auch zu interessanten Seiteneffekten, wie z.B. "Blockaden", führen. Und die dann aufzuklären - viel Spaß !