System.Threading.Thread-Klasse

Dieser Artikel enthält ergänzende Hinweise zur Referenzdokumentation für diese API.

Die Thread Klasse erstellt und steuert einen Thread, legt seine Priorität fest und ruft den Status ab.

Wenn ein Prozess gestartet wird, erstellt die Common Language Runtime automatisch einen einzelnen Vordergrundthread zum Ausführen von Anwendungscode. Zusammen mit diesem Standard Vordergrundthread kann ein Prozess einen oder mehrere Threads erstellen, um einen Teil des Programmcodes auszuführen, der dem Prozess zugeordnet ist. Diese Threads können entweder im Vordergrund oder im Hintergrund ausgeführt werden. Darüber hinaus können Sie die ThreadPool Klasse verwenden, um Code in Arbeitsthreads auszuführen, die von der Common Language Runtime verwaltet werden.

Starten eines Threads

Sie starten einen Thread, indem Sie einen Delegaten bereitstellen, der die Methode darstellt, die der Thread in seinem Klassenkonstruktor ausführen soll. Anschließend rufen Sie die Methode auf, um mit der Start Ausführung zu beginnen.

Die Thread Konstruktoren können einen von zwei Delegattypen verwenden, je nachdem, ob Sie ein Argument an die auszuführende Methode übergeben können:

  • Wenn die Methode keine Argumente enthält, übergeben Sie einen ThreadStart Delegaten an den Konstruktor. Sie hat die Signatur:

    public delegate void ThreadStart()
    
    Public Delegate Sub ThreadStart()
    

    Im folgenden Beispiel wird ein Thread erstellt und gestartet, der die ExecuteInForeground Methode ausführt. Die Methode zeigt Informationen zu einigen Threadeigenschaften an, führt dann eine Schleife aus, in der sie für eine halbe Sekunde angehalten wird, und zeigt die verstrichene Anzahl von Sekunden an. Wenn der Thread mindestens fünf Sekunden ausgeführt wurde, endet die Schleife, und der Thread beendet die Ausführung.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    public class Example2
    {
       public static void Main()
       {
          var th = new Thread(ExecuteInForeground);
          th.Start();
          Thread.Sleep(1000);
          Console.WriteLine("Main thread ({0}) exiting...",
                            Thread.CurrentThread.ManagedThreadId);
       }
    
       private static void ExecuteInForeground()
       {
          var sw = Stopwatch.StartNew();
          Console.WriteLine("Thread {0}: {1}, Priority {2}",
                            Thread.CurrentThread.ManagedThreadId,
                            Thread.CurrentThread.ThreadState,
                            Thread.CurrentThread.Priority);
          do {
             Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
                               Thread.CurrentThread.ManagedThreadId,
                               sw.ElapsedMilliseconds / 1000.0);
             Thread.Sleep(500);
          } while (sw.ElapsedMilliseconds <= 5000);
          sw.Stop();
       }
    }
    // The example displays output like the following:
    //       Thread 3: Running, Priority Normal
    //       Thread 3: Elapsed 0.00 seconds
    //       Thread 3: Elapsed 0.51 seconds
    //       Main thread (1) exiting...
    //       Thread 3: Elapsed 1.02 seconds
    //       Thread 3: Elapsed 1.53 seconds
    //       Thread 3: Elapsed 2.05 seconds
    //       Thread 3: Elapsed 2.55 seconds
    //       Thread 3: Elapsed 3.07 seconds
    //       Thread 3: Elapsed 3.57 seconds
    //       Thread 3: Elapsed 4.07 seconds
    //       Thread 3: Elapsed 4.58 seconds
    
    open System.Diagnostics
    open System.Threading
    
    let executeInForeground () =
        let sw = Stopwatch.StartNew()
    
        printfn $"Thread {Thread.CurrentThread.ManagedThreadId}: {Thread.CurrentThread.ThreadState}, Priority {Thread.CurrentThread.Priority}"
    
        while sw.ElapsedMilliseconds <= 5000 do
            printfn $"Thread {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000L:N2} seconds"
            Thread.Sleep 500
    
        sw.Stop()
    
    let th = Thread executeInForeground
    th.Start()
    Thread.Sleep 1000
    printfn $"Main thread ({Thread.CurrentThread.ManagedThreadId}) exiting..."
    
    // The example displays output like the following:
    //       Thread 3: Running, Priority Normal
    //       Thread 3: Elapsed 0.00 seconds
    //       Thread 3: Elapsed 0.51 seconds
    //       Main thread (1) exiting...
    //       Thread 3: Elapsed 1.02 seconds
    //       Thread 3: Elapsed 1.53 seconds
    //       Thread 3: Elapsed 2.05 seconds
    //       Thread 3: Elapsed 2.55 seconds
    //       Thread 3: Elapsed 3.07 seconds
    //       Thread 3: Elapsed 3.57 seconds
    //       Thread 3: Elapsed 4.07 seconds
    //       Thread 3: Elapsed 4.58 seconds
    
    Imports System.Diagnostics
    Imports System.Threading
    
    Module Example3
        Public Sub Main()
            Dim th As New Thread(AddressOf ExecuteInForeground)
            th.Start()
            Thread.Sleep(1000)
            Console.WriteLine("Main thread ({0}) exiting...", Thread.CurrentThread.ManagedThreadId)
        End Sub
    
        Private Sub ExecuteInForeground()
            Dim start As DateTime = DateTime.Now
            Dim sw As Stopwatch = Stopwatch.StartNew()
            Console.WriteLine("Thread {0}: {1}, Priority {2}",
                            Thread.CurrentThread.ManagedThreadId,
                            Thread.CurrentThread.ThreadState,
                            Thread.CurrentThread.Priority)
            Do
                Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
                               Thread.CurrentThread.ManagedThreadId,
                               sw.ElapsedMilliseconds / 1000)
                Thread.Sleep(500)
            Loop While sw.ElapsedMilliseconds <= 5000
            sw.Stop()
        End Sub
    End Module
    ' The example displays output like the following:
    '       Thread 3: Running, Priority Normal
    '       Thread 3: Elapsed 0.00 seconds
    '       Thread 3: Elapsed 0.51 seconds
    '       Main thread (1) exiting...
    '       Thread 3: Elapsed 1.02 seconds
    '       Thread 3: Elapsed 1.53 seconds
    '       Thread 3: Elapsed 2.05 seconds
    '       Thread 3: Elapsed 2.55 seconds
    '       Thread 3: Elapsed 3.07 seconds
    '       Thread 3: Elapsed 3.57 seconds
    '       Thread 3: Elapsed 4.07 seconds
    '       Thread 3: Elapsed 4.58 seconds
    
  • Wenn die Methode über ein Argument verfügt, übergeben Sie einen ParameterizedThreadStart Delegaten an den Konstruktor. Sie hat die Signatur:

    public delegate void ParameterizedThreadStart(object obj)
    
    Public Delegate Sub ParameterizedThreadStart(obj As Object)
    

    Die vom Delegaten ausgeführte Methode kann dann (in C#) oder (in Visual Basic) den Parameter in den entsprechenden Typ umwandeln.

    Das folgende Beispiel ist identisch mit dem vorherigen Beispiel, mit der Ausnahme, dass er den Thread(ParameterizedThreadStart) Konstruktor aufruft. Diese Version der ExecuteInForeground Methode weist einen einzelnen Parameter auf, der die ungefähre Anzahl von Millisekunden darstellt, die die Schleife ausführen soll.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    public class Example3
    {
       public static void Main()
       {
          var th = new Thread(ExecuteInForeground);
          th.Start(4500);
          Thread.Sleep(1000);
          Console.WriteLine("Main thread ({0}) exiting...",
                            Thread.CurrentThread.ManagedThreadId);
       }
    
       private static void ExecuteInForeground(Object obj)
       {
          int interval;
          try {
             interval = (int) obj;
          }
          catch (InvalidCastException) {
             interval = 5000;
          }
          var sw = Stopwatch.StartNew();
          Console.WriteLine("Thread {0}: {1}, Priority {2}",
                            Thread.CurrentThread.ManagedThreadId,
                            Thread.CurrentThread.ThreadState,
                            Thread.CurrentThread.Priority);
          do {
             Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
                               Thread.CurrentThread.ManagedThreadId,
                               sw.ElapsedMilliseconds / 1000.0);
             Thread.Sleep(500);
          } while (sw.ElapsedMilliseconds <= interval);
          sw.Stop();
       }
    }
    // The example displays output like the following:
    //       Thread 3: Running, Priority Normal
    //       Thread 3: Elapsed 0.00 seconds
    //       Thread 3: Elapsed 0.52 seconds
    //       Main thread (1) exiting...
    //       Thread 3: Elapsed 1.03 seconds
    //       Thread 3: Elapsed 1.55 seconds
    //       Thread 3: Elapsed 2.06 seconds
    //       Thread 3: Elapsed 2.58 seconds
    //       Thread 3: Elapsed 3.09 seconds
    //       Thread 3: Elapsed 3.61 seconds
    //       Thread 3: Elapsed 4.12 seconds
    
    open System
    open System.Diagnostics
    open System.Threading
    
    let executeInForeground obj =
        let interval =
            try
                unbox<int> obj
            with :? InvalidCastException ->
                5000
    
        let sw = Stopwatch.StartNew()
    
        printfn $"Thread {Thread.CurrentThread.ManagedThreadId}: {Thread.CurrentThread.ThreadState}, Priority {Thread.CurrentThread.Priority}"
    
        while sw.ElapsedMilliseconds <= interval do
            printfn $"Thread {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000L:N2} seconds"
            Thread.Sleep 500
    
        sw.Stop()
    
    let th = Thread(ParameterizedThreadStart executeInForeground)
    th.Start 4500
    Thread.Sleep 1000
    printfn $"Main thread ({Thread.CurrentThread.ManagedThreadId}) exiting..."
    
    // The example displays output like the following:
    //       Thread 3: Running, Priority Normal
    //       Thread 3: Elapsed 0.00 seconds
    //       Thread 3: Elapsed 0.52 seconds
    //       Main thread (1) exiting...
    //       Thread 3: Elapsed 1.03 seconds
    //       Thread 3: Elapsed 1.55 seconds
    //       Thread 3: Elapsed 2.06 seconds
    //       Thread 3: Elapsed 2.58 seconds
    //       Thread 3: Elapsed 3.09 seconds
    //       Thread 3: Elapsed 3.61 seconds
    //       Thread 3: Elapsed 4.12 seconds
    
    Imports System.Diagnostics
    Imports System.Threading
    
    Module Example4
        Public Sub Main()
            Dim th As New Thread(AddressOf ExecuteInForeground)
            th.Start(4500)
            Thread.Sleep(1000)
            Console.WriteLine("Main thread ({0}) exiting...", Thread.CurrentThread.ManagedThreadId)
        End Sub
    
        Private Sub ExecuteInForeground(obj As Object)
            Dim interval As Integer
            If IsNumeric(obj) Then
                interval = CInt(obj)
            Else
                interval = 5000
            End If
            Dim start As DateTime = DateTime.Now
            Dim sw As Stopwatch = Stopwatch.StartNew()
            Console.WriteLine("Thread {0}: {1}, Priority {2}",
                            Thread.CurrentThread.ManagedThreadId,
                            Thread.CurrentThread.ThreadState,
                            Thread.CurrentThread.Priority)
            Do
                Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
                               Thread.CurrentThread.ManagedThreadId,
                               sw.ElapsedMilliseconds / 1000)
                Thread.Sleep(500)
            Loop While sw.ElapsedMilliseconds <= interval
            sw.Stop()
        End Sub
    End Module
    ' The example displays output like the following:
    '       Thread 3: Running, Priority Normal
    '       Thread 3: Elapsed 0.00 seconds
    '       Thread 3: Elapsed 0.52 seconds
    '       Main thread (1) exiting...
    '       Thread 3: Elapsed 1.03 seconds
    '       Thread 3: Elapsed 1.55 seconds
    '       Thread 3: Elapsed 2.06 seconds
    '       Thread 3: Elapsed 2.58 seconds
    '       Thread 3: Elapsed 3.09 seconds
    '       Thread 3: Elapsed 3.61 seconds
    '       Thread 3: Elapsed 4.12 seconds
    

Es ist nicht erforderlich, einen Verweis auf ein Thread Objekt beizubehalten, nachdem Sie den Thread gestartet haben. Der Thread wird weiterhin ausgeführt, bis die Threadprozedur abgeschlossen ist.

Abrufen von Threadobjekten

Sie können die statische (Shared in Visual Basic) CurrentThread -Eigenschaft verwenden, um einen Verweis auf den derzeit ausgeführten Thread aus dem Code abzurufen, den der Thread ausführt. Im folgenden Beispiel wird die CurrentThread Eigenschaft verwendet, um Informationen zum Standard Anwendungsthread, einem anderen Vordergrundthread, einem Hintergrundthread und einem Threadpoolthread anzuzeigen.

using System;
using System.Threading;

public class Example1
{
   static Object obj = new Object();
   
   public static void Main()
   {
      ThreadPool.QueueUserWorkItem(ShowThreadInformation);
      var th1 = new Thread(ShowThreadInformation);
      th1.Start();
      var th2 = new Thread(ShowThreadInformation);
      th2.IsBackground = true;
      th2.Start();
      Thread.Sleep(500);
      ShowThreadInformation(null); 
   }
   
   private static void ShowThreadInformation(Object state)
   {
      lock (obj) {
         var th  = Thread.CurrentThread;
         Console.WriteLine("Managed thread #{0}: ", th.ManagedThreadId);
         Console.WriteLine("   Background thread: {0}", th.IsBackground);
         Console.WriteLine("   Thread pool thread: {0}", th.IsThreadPoolThread);
         Console.WriteLine("   Priority: {0}", th.Priority);
         Console.WriteLine("   Culture: {0}", th.CurrentCulture.Name);
         Console.WriteLine("   UI culture: {0}", th.CurrentUICulture.Name);
         Console.WriteLine();
      }   
   }
}
// The example displays output like the following:
//       Managed thread #6:
//          Background thread: True
//          Thread pool thread: False
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
//       
//       Managed thread #3:
//          Background thread: True
//          Thread pool thread: True
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
//       
//       Managed thread #4:
//          Background thread: False
//          Thread pool thread: False
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
//       
//       Managed thread #1:
//          Background thread: False
//          Thread pool thread: False
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
open System.Threading

let obj = obj ()

let showThreadInformation (state: obj) =
    lock obj (fun () ->
        let th = Thread.CurrentThread
        printfn $"Managed thread #{th.ManagedThreadId}: "
        printfn $"   Background thread: {th.IsBackground}"
        printfn $"   Thread pool thread: {th.IsThreadPoolThread}"
        printfn $"   Priority: {th.Priority}"
        printfn $"   Culture: {th.CurrentCulture.Name}"
        printfn $"   UI culture: {th.CurrentUICulture.Name}"
        printfn "")

ThreadPool.QueueUserWorkItem showThreadInformation |> ignore
let th1 = Thread(ParameterizedThreadStart showThreadInformation)
th1.Start()
let th2 = Thread(ParameterizedThreadStart showThreadInformation)
th2.IsBackground <- true
th2.Start()
Thread.Sleep 500
showThreadInformation ()

// The example displays output like the following:
//       Managed thread #6:
//          Background thread: True
//          Thread pool thread: False
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
//
//       Managed thread #3:
//          Background thread: True
//          Thread pool thread: True
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
//
//       Managed thread #4:
//          Background thread: False
//          Thread pool thread: False
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
//
//       Managed thread #1:
//          Background thread: False
//          Thread pool thread: False
//          Priority: Normal
//          Culture: en-US
//          UI culture: en-US
Imports System.Threading

Module Example2
    Private lock As New Object()

    Public Sub Main()
        ThreadPool.QueueUserWorkItem(AddressOf ShowThreadInformation)
        Dim th1 As New Thread(AddressOf ShowThreadInformation)
        th1.Start()
        Dim th2 As New Thread(AddressOf ShowThreadInformation)
        th2.IsBackground = True
        th2.Start()
        Thread.Sleep(500)
        ShowThreadInformation(Nothing)
    End Sub

    Private Sub ShowThreadInformation(state As Object)
        SyncLock lock
            Dim th As Thread = Thread.CurrentThread
            Console.WriteLine("Managed thread #{0}: ", th.ManagedThreadId)
            Console.WriteLine("   Background thread: {0}", th.IsBackground)
            Console.WriteLine("   Thread pool thread: {0}", th.IsThreadPoolThread)
            Console.WriteLine("   Priority: {0}", th.Priority)
            Console.WriteLine("   Culture: {0}", th.CurrentCulture.Name)
            Console.WriteLine("   UI culture: {0}", th.CurrentUICulture.Name)
            Console.WriteLine()
        End SyncLock
    End Sub
End Module
' The example displays output like the following:
'       ' Managed thread #6:
'          Background thread: True
'          Thread pool thread: False
'          Priority: Normal
'          Culture: en-US
'          UI culture: en-US
'       
'       Managed thread #3:
'          Background thread: True
'          Thread pool thread: True
'          Priority: Normal
'          Culture: en-US
'          UI culture: en-US
'       
'       Managed thread #4:
'          Background thread: False
'          Thread pool thread: False
'          Priority: Normal
'          Culture: en-US
'          UI culture: en-US
'       
'       Managed thread #1:
'          Background thread: False
'          Thread pool thread: False
'          Priority: Normal
'          Culture: en-US
'          UI culture: en-US

Vordergrund- und Hintergrundthreads

Instanzen der Thread Klasse stellen Vordergrundthreads oder Hintergrundthreads dar. Hintergrundthreads sind identisch mit Vordergrundthreads mit einer Ausnahme: Ein Hintergrundthread wird nicht ausgeführt, wenn alle Vordergrundthreads beendet wurden. Sobald alle Vordergrundthreads beendet wurden, beendet die Laufzeit alle Hintergrundthreads und beendet.

Standardmäßig werden die folgenden Threads im Vordergrund ausgeführt:

  • Der Standard Anwendungsthread.

  • Alle Threads, die durch Aufrufen eines Thread Klassenkonstruktors erstellt wurden.

Die folgenden Threads werden standardmäßig im Hintergrund ausgeführt:

  • Threadpoolthreads, die aus einem Pool von Arbeitsthreads stammen, Standard von der Laufzeit enthalten sind. Sie können den Threadpool konfigurieren und die Arbeit an Threadpoolthreads mithilfe der ThreadPool Klasse planen.

    Hinweis

    Aufgabenbasierte asynchrone Vorgänge werden automatisch in Threadpoolthreads ausgeführt. Aufgabenbasierte asynchrone Vorgänge verwenden die Task und Task<TResult> Klassen, um das aufgabenbasierte asynchrone Muster zu implementieren.

  • Alle Threads, die aus nicht verwaltetem Code in die verwaltete Ausführungsumgebung gelangen.

Sie können einen Thread ändern, der im Hintergrund ausgeführt wird, indem Sie die IsBackground Eigenschaft jederzeit festlegen. Hintergrundthreads sind nützlich für alle Vorgänge, die fortgesetzt werden sollen, solange eine Anwendung ausgeführt wird, aber nicht verhindern sollte, dass die Anwendung beendet wird, z. B. Überwachen von Dateisystemänderungen oder eingehenden Socketverbindungen.

Das folgende Beispiel veranschaulicht den Unterschied zwischen Vordergrund- und Hintergrundthreads. Es ist wie das erste Beispiel im Abschnitt "Thread starten ", mit der Ausnahme, dass der Thread vor dem Starten im Hintergrund ausgeführt werden soll. Wie die Ausgabe zeigt, wird die Schleife unterbrochen, bevor sie fünf Sekunden lang ausgeführt wird.

using System;
using System.Diagnostics;
using System.Threading;

public class Example
{
   public static void Main()
   {
      var th = new Thread(ExecuteInForeground);
      th.IsBackground = true;
      th.Start();
      Thread.Sleep(1000);
      Console.WriteLine("Main thread ({0}) exiting...",
                        Thread.CurrentThread.ManagedThreadId);
   }

   private static void ExecuteInForeground()
   {
      var sw = Stopwatch.StartNew();
      Console.WriteLine("Thread {0}: {1}, Priority {2}",
                        Thread.CurrentThread.ManagedThreadId,
                        Thread.CurrentThread.ThreadState,
                        Thread.CurrentThread.Priority);
      do {
         Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
                           Thread.CurrentThread.ManagedThreadId,
                           sw.ElapsedMilliseconds / 1000.0);
         Thread.Sleep(500);
      } while (sw.ElapsedMilliseconds <= 5000);
      sw.Stop();
   }
}
// The example displays output like the following:
//       Thread 3: Background, Priority Normal
//       Thread 3: Elapsed 0.00 seconds
//       Thread 3: Elapsed 0.51 seconds
//       Main thread (1) exiting...
open System.Diagnostics
open System.Threading

let executeInForeground () =
    let sw = Stopwatch.StartNew()
    printfn $"Thread {Thread.CurrentThread.ManagedThreadId}: {Thread.CurrentThread.ThreadState}, Priority {Thread.CurrentThread.Priority}"
    while sw.ElapsedMilliseconds <= 5000 do
        printfn $"Thread {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000L:N2} seconds"
        Thread.Sleep 500
    sw.Stop()

let th = Thread executeInForeground
th.IsBackground <- true
th.Start()
Thread.Sleep 1000
printfn $"Main thread ({Thread.CurrentThread.ManagedThreadId}) exiting..."

// The example displays output like the following:
//       Thread 3: Background, Priority Normal
//       Thread 3: Elapsed 0.00 seconds
//       Thread 3: Elapsed 0.51 seconds
//       Main thread (1) exiting...
Imports System.Diagnostics
Imports System.Threading

Module Example1
    Public Sub Main()
        Dim th As New Thread(AddressOf ExecuteInForeground)
        th.IsBackground = True
        th.Start()
        Thread.Sleep(1000)
        Console.WriteLine("Main thread ({0}) exiting...", Thread.CurrentThread.ManagedThreadId)
    End Sub

    Private Sub ExecuteInForeground()
        Dim start As DateTime = DateTime.Now
        Dim sw As Stopwatch = Stopwatch.StartNew()
        Console.WriteLine("Thread {0}: {1}, Priority {2}",
                        Thread.CurrentThread.ManagedThreadId,
                        Thread.CurrentThread.ThreadState,
                        Thread.CurrentThread.Priority)
        Do
            Console.WriteLine("Thread {0}: Elapsed {1:N2} seconds",
                           Thread.CurrentThread.ManagedThreadId,
                           sw.ElapsedMilliseconds / 1000)
            Thread.Sleep(500)
        Loop While sw.ElapsedMilliseconds <= 5000
        sw.Stop()
    End Sub
End Module
' The example displays output like the following:
'       Thread 3: Background, Priority Normal
'       Thread 3: Elapsed 0.00 seconds
'       Thread 3: Elapsed 0.51 seconds
'       Main thread (1) exiting...

Kultur und Threads

Jeder Thread verfügt über eine Kultur, dargestellt durch die CurrentCulture Eigenschaft und eine Benutzeroberflächenkultur, die durch die CurrentUICulture Eigenschaft dargestellt wird. Die aktuelle Kultur unterstützt kultursensitive Vorgänge, z. B. Analysieren und Formatieren, Zeichenfolgenvergleich und Sortierung, und steuert außerdem das Von einem Thread verwendete Schreibsystem und Kalender. Die aktuelle Benutzeroberflächenkultur ermöglicht das kultursensitive Abrufen von Ressourcen in Ressourcendateien.

Wichtig

Die CurrentCulture Eigenschaften funktionieren CurrentUICulture nicht zuverlässig, wenn sie mit einem anderen Thread als dem aktuellen Thread verwendet werden. In .NET Framework ist das Lesen dieser Eigenschaften zuverlässig, obwohl das Festlegen dieser Eigenschaften für einen anderen Thread als den aktuellen Thread nicht der Fall ist. Bei .NET Core wird ein InvalidOperationException Fehler ausgelöst, wenn ein Thread versucht, diese Eigenschaften in einem anderen Thread zu lesen oder zu schreiben. Es wird empfohlen, die CultureInfo.CurrentCultureCultureInfo.CurrentUICulture aktuelle Kultur abzurufen und festzulegen.

Wenn ein neuer Thread instanziiert wird, werden seine Kultur und UI-Kultur durch die aktuelle Systemkultur und UI-Kultur definiert, nicht durch die Kultur und UI-Kultur des Threads, aus dem der neue Thread erstellt wird. Dies bedeutet z. B., dass bei der aktuellen Systemkultur Englisch (USA) und die aktuelle Kultur des primären Anwendungsthreads Französisch (Frankreich) ist, die Kultur eines neuen Threads, der durch Aufrufen des Thread(ParameterizedThreadStart) Konstruktors aus dem primären Thread erstellt wird, Englisch (USA) und nicht Französisch (Frankreich). Weitere Informationen finden Sie im Abschnitt "Kultur und Threads" des CultureInfo Klassenthemas.

Wichtig

Dies gilt nicht für Threads, die asynchrone Vorgänge für Apps ausführen, die auf .NET Framework 4.6 und höhere Versionen abzielen. In diesem Fall ist die Kultur und UI-Kultur Teil des Kontexts eines asynchronen Vorgangs; der Thread, in dem ein asynchroner Vorgang standardmäßig ausgeführt wird, erbt die Kultur und UI-Kultur des Threads, von dem der asynchrone Vorgang gestartet wurde. Weitere Informationen finden Sie im Abschnitt "Kultur und aufgabenbasierte asynchrone Vorgänge" der CultureInfo Klassenhinweise.

Sie können eine der folgenden Aktionen ausführen, um sicherzustellen, dass alle threads, die in einer Anwendung ausgeführt werden, dieselbe Kultur und Benutzeroberflächenkultur aufweisen:

Weitere Informationen und Beispiele finden Sie im Abschnitt "Kultur und Threads" der CultureInfo Klassenhinweise.

Abrufen von Informationen zu und Steuerungsthreads

Sie können eine Reihe von Eigenschaftswerten abrufen, die Informationen zu einem Thread bereitstellen. In einigen Fällen können Sie diese Eigenschaftswerte auch festlegen, um den Vorgang des Threads zu steuern. Zu diesen Threadeigenschaften gehören:

  • Einen Namen. Name ist eine schreibgeschützte Eigenschaft, mit der Sie einen Thread identifizieren können. Der Standardwert lautet null.

  • Ein Hashcode, den Sie abrufen können, indem Sie die GetHashCode Methode aufrufen. Der Hashcode kann verwendet werden, um einen Thread eindeutig zu identifizieren; für die Lebensdauer des Threads kollidiert der Hashcode nicht mit dem Wert von einem anderen Thread, unabhängig von der Anwendung Standard aus der Sie den Wert abrufen.

  • Eine Thread-ID. Der Wert der schreibgeschützten ManagedThreadId Eigenschaft wird von der Laufzeit zugewiesen und identifiziert einen Thread innerhalb des Prozesses eindeutig.

    Hinweis

    Eine Betriebssystem- ThreadId hat keine feste Beziehung zu einem verwalteten Thread, da ein nicht verwalteter Host die Beziehung zwischen verwalteten und nicht verwalteten Threads steuern kann. Insbesondere kann ein anspruchsvoller Host die CLR-Hosting-API verwenden, um viele verwaltete Threads für denselben Betriebssystemthread zu planen oder einen verwalteten Thread zwischen verschiedenen Betriebssystemthreads zu verschieben.

  • Der aktuelle Status des Threads. Für die Dauer des Vorhandenseins befindet sich ein Thread immer in einem oder mehreren der durch die ThreadState Eigenschaft definierten Zustände.

  • Eine Planungsprioritätsstufe, die von der ThreadPriority Eigenschaft definiert wird. Obwohl Sie diesen Wert so festlegen können, dass die Priorität eines Threads angefordert wird, ist es nicht garantiert, dass er vom Betriebssystem berücksichtigt wird.

  • Die schreibgeschützte IsThreadPoolThread Eigenschaft, die angibt, ob ein Thread ein Threadpoolthread ist.

  • Die IsBackground-Eigenschaft Weitere Informationen finden Sie im Abschnitt "Vordergrund- und Hintergrundthreads ".

Beispiele

Im folgenden Beispiel werden einfache Threadingfunktionen veranschaulicht.

using System;
using System.Threading;

// Simple threading scenario:  Start a static method running
// on a second thread.
public class ThreadExample {
    // The ThreadProc method is called when the thread starts.
    // It loops ten times, writing to the console and yielding
    // the rest of its time slice each time, and then ends.
    public static void ThreadProc() {
        for (int i = 0; i < 10; i++) {
            Console.WriteLine("ThreadProc: {0}", i);
            // Yield the rest of the time slice.
            Thread.Sleep(0);
        }
    }

    public static void Main() {
        Console.WriteLine("Main thread: Start a second thread.");
        // The constructor for the Thread class requires a ThreadStart
        // delegate that represents the method to be executed on the
        // thread.  C# simplifies the creation of this delegate.
        Thread t = new Thread(new ThreadStart(ThreadProc));

        // Start ThreadProc.  Note that on a uniprocessor, the new
        // thread does not get any processor time until the main thread
        // is preempted or yields.  Uncomment the Thread.Sleep that
        // follows t.Start() to see the difference.
        t.Start();
        //Thread.Sleep(0);

        for (int i = 0; i < 4; i++) {
            Console.WriteLine("Main thread: Do some work.");
            Thread.Sleep(0);
        }

        Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends.");
        t.Join();
        Console.WriteLine("Main thread: ThreadProc.Join has returned.  Press Enter to end program.");
        Console.ReadLine();
    }
}
open System.Threading

// Simple threading scenario:  Start a static method running
// on a second thread.

// The ThreadProc method is called when the thread starts.
// It loops ten times, writing to the console and yielding
// the rest of its time slice each time, and then ends.
let threadProc () =
    for i = 0 to 9 do
        printfn $"ThreadProc: {i}"
        // Yield the rest of the time slice.
        Thread.Sleep 0

printfn "Main thread: Start a second thread."
// The constructor for the Thread class requires a ThreadStart
// delegate that represents the method to be executed on the
// thread. F# simplifies the creation of this delegate.
let t = Thread threadProc

// Start ThreadProc.  Note that on a uniprocessor, the new
// thread does not get any processor time until the main thread
// is preempted or yields.  Uncomment the Thread.Sleep that
// follows t.Start() to see the difference.
t.Start()
//Thread.Sleep 0

for _ = 0 to 3 do
    printfn "Main thread: Do some work."
    Thread.Sleep 0

printfn "Main thread: Call Join(), to wait until ThreadProc ends."
t.Join()
printfn "Main thread: ThreadProc.Join has returned.  Press Enter to end program."
stdin.ReadLine() |> ignore
Imports System.Threading

' Simple threading scenario:  Start a Shared method running
' on a second thread.
Public Class ThreadExample
    ' The ThreadProc method is called when the thread starts.
    ' It loops ten times, writing to the console and yielding 
    ' the rest of its time slice each time, and then ends.
    Public Shared Sub ThreadProc()
        Dim i As Integer
        For i = 0 To 9
            Console.WriteLine("ThreadProc: {0}", i)
            ' Yield the rest of the time slice.
            Thread.Sleep(0)
        Next
    End Sub

    Public Shared Sub Main()
        Console.WriteLine("Main thread: Start a second thread.")
        ' The constructor for the Thread class requires a ThreadStart 
        ' delegate.  The Visual Basic AddressOf operator creates this
        ' delegate for you.
        Dim t As New Thread(AddressOf ThreadProc)

        ' Start ThreadProc.  Note that on a uniprocessor, the new 
        ' thread does not get any processor time until the main thread 
        ' is preempted or yields.  Uncomment the Thread.Sleep that 
        ' follows t.Start() to see the difference.
        t.Start()
        'Thread.Sleep(0)

        Dim i As Integer
        For i = 1 To 4
            Console.WriteLine("Main thread: Do some work.")
            Thread.Sleep(0)
        Next

        Console.WriteLine("Main thread: Call Join(), to wait until ThreadProc ends.")
        t.Join()
        Console.WriteLine("Main thread: ThreadProc.Join has returned.  Press Enter to end program.")
        Console.ReadLine()
    End Sub
End Class

Dieser Code erzeugt eine Ausgabe ähnlich wie die folgenden:

[VB, C++, C#]
Main thread: Start a second thread.
Main thread: Do some work.
ThreadProc: 0
Main thread: Do some work.
ThreadProc: 1
Main thread: Do some work.
ThreadProc: 2
Main thread: Do some work.
ThreadProc: 3
Main thread: Call Join(), to wait until ThreadProc ends.
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
Main thread: ThreadProc.Join has returned. Press Enter to end program.