Ein Thread ist als Ausführungspfad eines Programms definiert. Jeder Thread definiert eine einzigartige Flusskontrolle. Wenn Ihre Anwendung komplexe und zeitaufwändige Vorgänge umfasst, wie z. B. Datenbankzugriffe oder einige intensive E/A-Vorgänge, dann ist es oft sehr vorteilhaft, verschiedene Ausführungspfade oder Threads einzurichten, wobei jeder Thread eine bestimmte Aufgabe ausführt.
Threads sind leichte Prozesse. Ein häufiges Beispiel für den Einsatz von Threads ist die Implementierung paralleler Programmierung in modernen Betriebssystemen. Die Verwendung von Threads erspart den Verlust von CPU-Zyklen und verbessert die Anwendungseffizienz.
Das Programm, das wir bisher kompiliert haben, läuft als einzelner Prozess in einem Thread, der die laufende Instanz der Anwendung ist. Allerdings kann eine solche Anwendung jeweils nur einen Job ausführen. Damit es mehrere Aufgaben gleichzeitig ausführen kann, können Sie es in kleinere Threads aufteilen.
In .Net werden Threads über den Namespace „System.Threading“ verarbeitet. Durch das Erstellen einer Variablen vom Typ system.threading.thread können Sie einen neuen Thread erstellen und mit der Arbeit daran beginnen. Es ermöglicht Ihnen, unabhängige Threads in einem separaten Thread zu erstellen und darauf zuzugreifen.
Ein Thread wird aus einem Thread-Objekt erstellt und sein Konstruktor erhält eine Referenz zum Starten des Threads.
ThreadStart childthreat = new ThreadStart(childthreadcall);
Der Lebenszyklus eines Threads beginnt, wenn ein Objekt der Klasse system.threading.thread erstellt wird, und endet, wenn der Thread beendet oder die Ausführung abgeschlossen ist.
Im Folgenden sind die verschiedenen Zustände im Lebenszyklus eines Threads aufgeführt:
Ausstehender Startstatus: Die Instanz des Threads wurde erstellt, aber die Startmethode wurde nicht aufgerufen.
Bereitzustand: Eine Situation, in der ein Thread zur Ausführung bereit ist und auf einen CPU-Zyklus wartet.
Nicht ausführbarer Zustand: Wenn ein Thread nicht ausgeführt werden kann, gibt es mehrere Möglichkeiten:
Die aktuelle Schlafmethode wird aufgerufen
Die Wartemethode wird aufgerufen
Durch E/A-Vorgang blockiert
Todeszustand: Der Thread hat die Ausführung abgeschlossen oder wurde beendet.
Das Priority-Attribut in der Thread-Klasse gibt hauptsächlich die Priorität eines Threads im Verhältnis zu anderen Threads an. Die .NET-Laufzeit wählt den bereiten Thread mit der höchsten Priorität aus. Die Priorität kann unterteilt werden in:
höher als normal
niedriger als normal
Höchste
am niedrigsten
Normal
Sobald ein Thread erstellt wurde, legt das System seine Priorität mithilfe des Prioritätseinstellungssystems der Thread-Klasse fest.
NewThread.Priority = ThreadPriority.Highest;
Die Thread-Klasse verfügt über die folgenden wichtigen Funktionen:
Eigentum | beschreiben |
---|---|
AktuellerKontext | Rufen Sie den Inhalt des aktuell ausgeführten Threads ab. |
AktuelleKultur | Ruft die Umgebung des aktuellen Threads ab oder legt diese fest. |
AktuellesPrinzip | Ruft die rollenbasierte Sicherheitsrichtlinie des aktuellen Prozesses ab oder legt diese fest. |
Aktueller Thread | Ruft den aktuell laufenden Thread ab. |
AktuelleUIKultur | Ruft die aktuelle Umgebung ab, die vom Ressourcenmanager des aktuell ausgeführten Prozesses verwendet wird, um bestimmte Ressourcen zu finden, oder legt diese fest. |
Ausführungskontext | Ruft ein ExecutionContext-Objekt ab, das Kontextinformationen zum aktuellen Thread enthält. |
IsAlive | Ruft einen Wert ab, der den Ausführungsstatus des aktuellen Threads angibt. |
IsBackground | Hintergrund Ruft einen Wert ab oder legt ihn fest, der angibt, ob der Thread ein Hintergrundthread ist. |
IsThreadPoolThread | Ruft einen Wert ab, der angibt, ob der Thread zum verwalteten Thread-Pool gehört. |
ManagedThreadId | Ruft den aktuellen eindeutigen Bezeichner des verwalteten Threads ab. |
Name | Ruft den Namen des Threads ab oder legt diesen fest. |
Priorität | Ruft einen Wert ab, der die Planungspriorität eines Threads angibt, oder legt diesen fest. |
ThreadState | Ruft einen Wert ab, der den Status des aktuellen Threads enthält. |
Die Thread-Klasse verfügt über die folgenden wichtigen Methoden:
Verfahren | beschreiben |
---|---|
Abbrechen | Durch den Aufruf einer ThreadAbortException wird der Thread-Beendigungsprozess eingeleitet. |
AllocateDataSlot | Allen Threads wird ein unbenannter Datenslot zugewiesen. Für eine bessere Leistung verwenden Sie Felder, die mit dem ThreadStaticAttribute-Attribut gekennzeichnet sind. |
AllocateNamedDataSlot | Weisen Sie allen Threads benannte Datenslots zu. Für eine bessere Leistung verwenden Sie Felder, die mit dem ThreadStaticAttribute-Attribut gekennzeichnet sind. |
BeginCriticalRegion | Benachrichtigt den Host darüber, dass die Ausführung im Begriff ist, in einen Codebereich zu gelangen, in dem die Auswirkungen eines Thread-Abbruchs oder einer nicht behandelten Ausnahme andere Aufgaben gefährden könnten. |
BeginThreadAffinity | Benachrichtigt den Host darüber, dass verwalteter Code ausgeführt werden soll, abhängig von der Identität des aktuellen physischen Betriebssystem-Threads. |
EndCriticalRegion | Benachrichtigt den Host darüber, dass die Ausführung im Begriff ist, in einen Codebereich zu gelangen, in dem ein Thread-Abbruch oder eine nicht behandelte Ausnahme nur die aktuelle Aufgabe betrifft. |
EndThreadAffinity | Benachrichtigt den Host, dass die Ausführung des verwalteten Codes abgeschlossen ist, abhängig von der Identität des aktuellen physischen Betriebssystem-Threads. |
FreeNamedDataSlot | Beseitigt die Zuordnung zwischen Namen und Slots für alle Threads im Prozess. Verwenden Sie für eine bessere Leistung Felder, die mit dem ThreadStaticAttribute-Attribut gekennzeichnet sind. |
GetData | Ruft den Wert aus dem vom aktuellen Thread angegebenen Slot in der aktuellen Domäne des aktuellen Threads ab. Für eine bessere Leistung verwenden Sie Felder, die mit dem ThreadStaticAttribute-Attribut gekennzeichnet sind. |
GetDomain | Gibt den aktuell ausgeführten Thread in der aktuellen Domäne zurück. |
GetDomainID | Gibt die eindeutige Anwendungsdomänenkennung zurück. |
GetNamedDataSlot | Suchen Sie einen benannten Datenslot. Für eine bessere Leistung verwenden Sie Felder, die mit dem ThreadStaticAttribute-Attribut gekennzeichnet sind. |
Unterbrechen | Unterbrechen Sie einen Thread im WaitSleepJoin-Thread-Status. |
Verbinden | Blockiert den aufrufenden Thread, bis einer der Threads beendet wird, während die standardmäßige COM- und SendMessage-Ausführung fortgesetzt wird. Diese Methode hat verschiedene überladene Formen. |
Speicherbarriere | Synchrone Speicherzugriffe sind wie folgt: Der Beschleuniger, der den aktuellen Thread verarbeitet, kann Anweisungen nicht so umordnen, dass der Speicherzugriff MemoryBarrier aufruft und anschließend der Speicherzugriff ausgeführt wird. |
ResetAbort | Bricht die Abbruchanforderung des aktuellen Threads ab. |
SetData | Legt die Daten für den aktuell laufenden Thread im angegebenen Zeitfenster und die aktuelle Domäne dieses Threads fest. Für eine bessere Leistung verfügt die Anwendungsdomäne über das ThreadStaticAttribute-Attribut der Domäne. |
Start | Starten Sie einen Thread. |
Schlafen | Bewirkt, dass der Thread für einen bestimmten Zeitraum angehalten wird. |
SpinWait | Lässt den Thread auf die durch den Parameter definierte Anzahl von Iterationen warten. |
VolatileRead() | Lesen Sie den Wert des Feldes. Der neueste Wert wird von jedem Prozessor des Computers geschrieben, unabhängig von der Prozessor- oder Prozessor-Cache-Statusnummer. Diese Methode hat verschiedene überladene Formen. |
VolatileWrite() | Schreibt sofort einen Wert in ein Feld, das für alle Prozessoren im Computer sichtbar ist. Diese Methode hat verschiedene überladene Formen. |
Ertrag | Veranlasst den aufrufenden Thread, einen anderen Thread auszuführen, der auf dem aktuellen Prozessor ausgeführt werden kann, und das Betriebssystem entscheidet sich für die Umleitung des Threads |
Das folgende Beispiel veranschaulicht die Verwendung von Thread-Klassen. Die Seite verfügt über eine Steuerelementbezeichnung, die Nachrichten von untergeordneten Threads anzeigt. Nachrichten vom Hauptprogramm werden direkt mit der Methode „response.write(50)“ angezeigt, sodass sie oben auf der Seite erscheinen.
Die Quelldateien lauten wie folgt:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="threaddemo._Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional// DE" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title> Unbenannte Seite </title> </head> <body> <form id="form1 " runat="server"> <div> <h3>Thread-Beispiel</h3> </div> <asp:Label ID="lblmessage" runat="server" Text="Label"> </asp:Label> < /form> </body> </html>
Der Hintergrundcode lautet wie folgt:
unter Verwendung von System.Collections; unter Verwendung von System.Web.UI; unter Verwendung von System.Web.UI ; using System.Web.UI.WebControls; using System.Xml.Linq; using System.Threading; class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e) { ThreadStart childthreat = new ThreadStart(childthreadcall); Response.Write("Child Thread Started <br/>"); Thread(childthreat); child.Start(); Response.Write("Hauptschlaf für 2 Sekunden....<br/>"); Thread.Sleep(2000); Response.Write("<br/>Hauptabbruch untergeordneter Thread<br/>"); child.Abort(); public void childthreadcall() { try{ lblmessage.Text = "<br/ >Untergeordneter Thread gestartet <br/>"; lblmessage.Text += "Untergeordneter Thread: Zählt auf 10"; for( int i =0; i<10; i++) { Thread.Sleep(500); lblmessage.Text += "<br/> im untergeordneten Thread </br>"; Catch(ThreadAbortException e){ lblmessage.Text += "<br /> untergeordneter Thread - Ausnahme"; „<br /> untergeordneter Thread – Ausnahme konnte nicht abgefangen werden“;
Beim Laden der Seite wird ein neuer Thread mit childthreadcall() als Referenz gestartet. Die Aktivitäten des Hauptthreads werden direkt auf der Webseite angezeigt.
Ein zweiter Thread wird ausgeführt und sendet die Nachricht an das Kontroll-Tag.
Der Hauptthread schläft 2000 Millisekunden lang, während der untergeordnete Thread ausgeführt wird.
Der untergeordnete Thread läuft weiter, bis er vom Hauptthread beendet wird. Anschließend löst er eine ThreadAbortException aus und wird beendet.
Die Steuerung kehrt zum Hauptthread zurück.
Bei der Ausführung sendet das Programm die folgenden Informationen: