Thread 类

定义

创建和控制线程,设置其优先级并获取其状态。Creates and controls a thread, sets its priority, and gets its status.

public ref class Thread sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject, System::Runtime::InteropServices::_Thread
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Thread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.Runtime.InteropServices._Thread
type Thread = class
    inherit CriticalFinalizerObject
    interface _Thread
Public NotInheritable Class Thread
Inherits CriticalFinalizerObject
Implements _Thread
继承
属性
实现

示例

下面的示例演示简单的线程处理功能。The following example demonstrates simple threading functionality.

// [C++]
// Compile using /clr option.
using namespace System;
using namespace System::Threading;

// Simple threading scenario:  Start a Shared method running
// on a second thread.
public ref class ThreadExample
{
public:

   // 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.
   static void ThreadProc()
   {
      for ( int i = 0; i < 10; i++ )
      {
         Console::Write(  "ThreadProc: " );
         Console::WriteLine( i );
         
         // Yield the rest of the time slice.
         Thread::Sleep( 0 );

      }
   }

};

int main()
{
   Console::WriteLine( "Main thread: Start a second thread." );
   
   // Create the thread, passing a ThreadStart delegate that
   // represents the ThreadExample::ThreadProc method.  For a 
   // delegate representing a static method, no object is
   // required.
   Thread^ oThread = gcnew Thread( gcnew ThreadStart( &ThreadExample::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 oThread->Start() to see the difference.
   oThread->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." );
   oThread->Join();
   Console::WriteLine(  "Main thread: ThreadProc.Join has returned.  Press Enter to end program." );
   Console::ReadLine();
   return 0;
}

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();
    }
}
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

此代码生成与下面类似的输出:This code produces output similar to the following:

[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.  

注解

进程启动时,公共语言运行时将自动创建单个前台线程以执行应用程序代码。When a process starts, the common language runtime automatically creates a single foreground thread to execute application code. 除了此主前台线程,进程还可以创建一个或多个线程来执行与进程关联的程序代码的一部分。Along with this main foreground thread, a process can create one or more threads to execute a portion of the program code associated with the process. 这些线程可以在前台或后台执行。These threads can execute either in the foreground or in the background. 此外,还可以使用 ThreadPool 类来执行由公共语言运行时管理的工作线程上的代码。In addition, you can use the ThreadPool class to execute code on worker threads that are managed by the common language runtime.

本节内容In this section

启动线程 Starting a thread
检索线程对象 Retrieving Thread objects
前台和后台线程 Foreground and background threads
区域性和线程 Culture and threads
获取和控制线程的相关信息Getting information about and controlling threads

启动线程Starting a thread

您可以通过提供委托来启动线程,该委托表示线程在其类构造函数中执行的方法。You start a thread by supplying a delegate that represents the method the thread is to execute in its class constructor. 然后调用 Start 方法开始执行。You then call the Start method to begin execution.

Thread 构造函数可以采用两种委托类型中的任意一种,具体取决于是否可以将参数传递给要执行的方法:The Thread constructors can take either of two delegate types, depending on whether you can pass an argument to the method to be executed:

  • 如果该方法没有参数,则将 ThreadStart 委托传递给构造函数。If the method has no arguments, you pass a ThreadStart delegate to the constructor. 它具有签名:It has the signature:

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

    下面的示例创建并启动一个线程来执行 ExecuteInForeground 方法。The following example creates and starts a thread that executes the ExecuteInForeground method. 方法显示有关某些线程属性的信息,然后执行循环,其中每半秒暂停一次,并显示已用的秒数。The method displays information about some thread properties, then executes a loop in which it pauses for half a second and displays the elapsed number of seconds. 当线程至少执行五秒后,循环结束,线程终止执行。When the thread has executed for at least five seconds, the loop ends and the thread terminates execution.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    public class Example
    {
       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()
       {
          DateTime start = DateTime.Now;
          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
    
    Imports System.Diagnostics
    Imports System.Threading
    
    Module Example
       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
    
  • 如果该方法具有参数,则将 ParameterizedThreadStart 委托传递给构造函数。If the method has an argument, you pass a ParameterizedThreadStart delegate to the constructor. 它具有签名:It has the signature:

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

    然后,由委托执行的方法可以将参数强制C#转换(在中)或将参数转换(Visual Basic)到相应的类型。The method executed by the delegate can then cast (in C#) or convert (in Visual Basic) the parameter to the appropriate type.

    下面的示例与上一个示例相同,不同之处在于它调用 Thread(ParameterizedThreadStart) 构造函数。The following example is identical to the previous one, except that it calls the Thread(ParameterizedThreadStart) constructor. 此版本的 ExecuteInForeground 方法有一个参数,该参数表示执行循环的大约毫秒数。This version of the ExecuteInForeground method has a single parameter that represents the approximate number of milliseconds the loop is to execute.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    public class Example
    {
       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;
          }
          DateTime start = DateTime.Now;
          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
    
    Imports System.Diagnostics
    Imports System.Threading
    
    Module Example
       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
    

启动线程后,不需要保留对 Thread 对象的引用。It is not necessary to retain a reference to a Thread object once you have started the thread. 线程将继续执行,直到线程过程完成。The thread continues to execute until the thread procedure is complete.

检索线程对象Retrieving Thread objects

可以使用 static (Shared Visual Basic) CurrentThread 属性从线程正在执行的代码中检索对当前正在执行的线程的引用。You can use the static (Shared in Visual Basic) CurrentThread property to retrieve a reference to the currently executing thread from the code that the thread is executing. 下面的示例使用 CurrentThread 属性显示有关主应用程序线程、另一个前台线程、一个后台线程和一个线程池线程的信息。The following example uses the CurrentThread property to display information about the main application thread, another foreground thread, a background thread, and a thread pool thread.

using System;
using System.Threading;

public class Example
{
   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
Imports System.Threading

Module Example
   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

前台和后台线程Foreground and background threads

Thread 类的实例表示前台线程或后台线程。Instances of the Thread class represent either foreground threads or background threads. 后台线程与前台线程完全相同,但有一种例外情况:如果所有前台线程均已终止,后台线程并不会使进程保持运行。Background threads are identical to foreground threads with one exception: a background thread does not keep a process running if all foreground threads have terminated. 所有前台线程停止后,运行时将停止所有后台线程并关闭。Once all foreground threads have been stopped, the runtime stops all background threads and shuts down.

默认情况下,以下线程在前台执行:By default, the following threads execute in the foreground:

  • 主应用程序线程。The main application thread.

  • 通过调用 Thread 类构造函数创建的所有线程。All threads created by calling a Thread class constructor.

默认情况下,以下线程在后台执行:The following threads execute in the background by default:

  • 线程池线程,线程池是由运行时维护的工作线程池。Thread pool threads, which are a pool of worker threads maintained by the runtime. 您可以使用 ThreadPool 类配置线程池和计划线程池线程上的工作。You can configure the thread pool and schedule work on thread pool threads by using the ThreadPool class.

    备注

    基于任务的异步操作会在线程池线程上自动执行。Task-based asynchronous operations automatically execute on thread pool threads. 基于任务的异步操作使用 TaskTask<TResult> 类实现基于任务的异步模式Task-based asynchronous operations use the Task and Task<TResult> classes to implement the task-based asynchronous pattern.

  • 从非托管代码进入托管执行环境的所有线程。All threads that enter the managed execution environment from unmanaged code.

你可以随时通过设置 "IsBackground" 属性来更改要在后台中执行的线程。You can change a thread to execute in the background by setting the IsBackground property at any time. 当应用程序正在运行但不应阻止应用程序终止时(如监视文件系统更改或传入套接字连接),后台线程适用于应该继续执行的任何操作。Background threads are useful for any operation that should continue as long as an application is running but should not prevent the application from terminating, such as monitoring file system changes or incoming socket connections.

下面的示例演示前台和后台线程之间的差异。The following example illustrates the difference between foreground and background threads. 它类似于启动线程部分中的第一个示例,只不过它会将线程设置为在后台执行,然后再启动它。It is like the first example in the Starting a thread section, except that it sets the thread to execute in the background before starting it. 如输出所示,循环在执行5秒之前中断。As the output shows, the loop is interrupted before it executes for five seconds.

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()
   {
      DateTime start = DateTime.Now;
      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...
Imports System.Diagnostics
Imports System.Threading

Module Example
   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...

区域性和线程Culture and threads

每个线程都具有由 CurrentCulture 属性表示的区域性,以及由 CurrentUICulture 属性表示的 UI 区域性。Each thread has a culture, represented by the CurrentCulture property, and a UI culture, represented by the CurrentUICulture property. 当前区域性支持诸如分析和格式化、字符串比较和排序等区分区域性的操作,还可控制线程使用的书写体系和日历。The current culture supports such culture-sensitive operations as parsing and formatting, string comparison and sorting, and also controls the writing system and calendar used by a thread. 当前 UI 区域性提供对资源文件中的资源进行区分区域性的检索。The current UI culture provides for culture-sensitive retrieval of resources in resource files.

重要

与当前线程以外的任何线程一起使用时,CurrentCultureCurrentUICulture 属性将无法可靠运行。The CurrentCulture and CurrentUICulture properties don't work reliably when used with any thread other than the current thread. 在 .NET Framework 中,虽然为当前线程以外的线程设置这些属性,但读取这些属性是可靠的。In .NET Framework, reading these properties is reliable, although setting these properties for a thread other than the current thread is not. 在 .NET Core 中,如果线程尝试在另一个线程上读取或写入这些属性,则会引发 InvalidOperationExceptionOn .NET Core, an InvalidOperationException is thrown if a thread attempts to read or write these properties on a different thread. 建议使用 CultureInfo.CurrentCultureCultureInfo.CurrentUICulture 属性检索和设置当前区域性。We recommend that you use the CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture properties to retrieve and set the current culture.

实例化新线程时,其区域性和 UI 区域性由当前系统区域性和 UI 区域性定义,而不是由从中创建新线程的线程的区域性和 UI 区域性定义。When a new thread is instantiated, its culture and UI culture are defined by the current system culture and UI culture, and not by the culture and UI culture of the thread from which the new thread is created. 这意味着,如果当前系统区域性为英语(美国)并且主应用程序线程的当前区域性为法语(法国),则通过从主线程调用 Thread(ParameterizedThreadStart) 构造函数创建的新线程的区域性为:英语(美国)和 not 法语(法国)。This means, for example, that if the current system culture is English (United States) and the current culture of the primary application thread is French (France), the culture of a new thread created by calling the Thread(ParameterizedThreadStart) constructor from the primary thread is English (United States), and not French (France). 有关详细信息,请参阅 CultureInfo 类主题中的 "区域性和线程" 一节。For more information, see the "Culture and threads" section of the CultureInfo class topic.

重要

对于面向 .NET Framework 4.6.NET Framework 4.6 和更高版本的应用程序执行异步操作的线程,这种情况并不是如此,在这种情况下,区域性和 UI 区域性是异步操作的上下文的一部分;默认情况下,执行异步操作的线程继承从中启动异步操作的线程的区域性和 UI 区域性。This is not true of threads that execute asynchronous operations for apps that target the .NET Framework 4.6.NET Framework 4.6 and later versions, In this case, the culture and UI culture is part of an asynchronous operations' context; the thread on which an asynchronous operation executes by default inherits the culture and UI culture of the thread from which the asynchronous operation was launched. 有关详细信息,请参阅 CultureInfo 类主题中的“区域性和基于任务的异步操作”一节。For more information, see the "Culture and task-based asynchronous operations" section of the CultureInfo class topic.

可以执行以下任一操作,以确保在应用程序中执行的所有线程共享相同的区域性和 UI 区域性:You can do either of the following to ensure that all of the threads executing in an application share the same culture and UI culture:

有关详细信息和示例,请参阅 CultureInfo 类主题中的 "区域性和线程" 一节。For more information and examples, see the "Culture and threads" section of the CultureInfo class topic.

获取和控制线程的相关信息Getting information about and controlling threads

您可以检索提供有关线程信息的多个属性值。You can retrieve a number of property values that provide information about a thread. 在某些情况下,还可以设置这些属性值来控制线程的操作。In some cases, you can also set these property values to control the operation of the thread. 这些线程属性包括:These thread properties include:

  • 名称。A name. Name 是一种只写的属性,可用于标识线程。Name is a write-once property that you can use to identify a thread. 它的默认值为 nullIts default value is null.

  • 哈希代码,可以通过调用 GetHashCode 方法来检索。A hash code, which you can retrieve by calling the GetHashCode method. 哈希代码可用于唯一标识线程;在线程的生存期内,无论从中获取值的应用程序域如何,其哈希代码都不会与其他任何线程的值相冲突。The hash code can be used to uniquely identify a thread; for the lifetime of your thread, its hash code will not collide with the value from any other thread, regardless of the application domain from which you obtain the value.

  • 线程 ID。A thread ID. 只读 ManagedThreadId 属性的值由运行时分配并在其进程中唯一标识一个线程。The value of the read-only ManagedThreadId property is assigned by the runtime and uniquely identifies a thread within its process.

    备注

    因为非托管主机可以控制托管线程和非托管线程之间的关系,所以操作系统 ThreadId 与托管线程之间没有固定的关系。An operating-system ThreadId has no fixed relationship to a managed thread, because an unmanaged host can control the relationship between managed and unmanaged threads. 具体而言,一个复杂的主机可以使用CLR 宿主 API为同一操作系统线程计划多个托管线程,或在不同的操作系统线程之间移动托管线程。Specifically, a sophisticated host can use the CLR Hosting API to schedule many managed threads against the same operating system thread, or to move a managed thread between different operating system threads.

  • 线程的当前状态。The thread's current state. 在其存在的持续时间内,线程始终处于由 ThreadState 属性定义的一个或多个状态。For the duration of its existence, a thread is always in one or more of the states defined by the ThreadState property.

  • 计划优先级级别,由 ThreadPriority 属性定义。A scheduling priority level, which is defined by the ThreadPriority property. 虽然您可以将此值设置为请求线程的优先级,但并不保证操作系统接受此值。Although you can set this value to request a thread's priority, it is not guaranteed to be honored by the operating system.

  • 只读 IsThreadPoolThread 属性,指示线程是否为线程池线程。The read-only IsThreadPoolThread property, which indicates whether a thread is a thread pool thread.

  • IsBackground 属性。The IsBackground property. 有关详细信息,请参阅前台和后台线程部分。For more information, see the Foreground and background threads section.

构造函数

Thread(ParameterizedThreadStart)

初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托。Initializes a new instance of the Thread class, specifying a delegate that allows an object to be passed to the thread when the thread is started.

Thread(ParameterizedThreadStart, Int32)

初始化 Thread 类的新实例,指定允许对象在线程启动时传递给线程的委托,并指定线程的最大堆栈大小。Initializes a new instance of the Thread class, specifying a delegate that allows an object to be passed to the thread when the thread is started and specifying the maximum stack size for the thread.

Thread(ThreadStart)

初始化 Thread 类的新实例。Initializes a new instance of the Thread class.

Thread(ThreadStart, Int32)

初始化 Thread 类的新实例,指定线程的最大堆栈大小。Initializes a new instance of the Thread class, specifying the maximum stack size for the thread.

属性

ApartmentState

获取或设置此线程的单元状态。Gets or sets the apartment state of this thread.

CurrentContext

获取线程正在其中执行的当前上下文。Gets the current context in which the thread is executing.

CurrentCulture

获取或设置当前线程的区域性。Gets or sets the culture for the current thread.

CurrentPrincipal

获取或设置线程的当前负责人(对基于角色的安全性而言)。Gets or sets the thread's current principal (for role-based security).

CurrentThread

获取当前正在运行的线程。Gets the currently running thread.

CurrentUICulture

获取或设置资源管理器使用的当前区域性以便在运行时查找区域性特定的资源。Gets or sets the current culture used by the Resource Manager to look up culture-specific resources at run time.

ExecutionContext

获取 ExecutionContext 对象,该对象包含有关当前线程的各种上下文的信息。Gets an ExecutionContext object that contains information about the various contexts of the current thread.

IsAlive

获取指示当前线程的执行状态的值。Gets a value indicating the execution status of the current thread.

IsBackground

获取或设置一个值,该值指示某个线程是否为后台线程。Gets or sets a value indicating whether or not a thread is a background thread.

IsThreadPoolThread

获取指示线程是否属于托管线程池的值。Gets a value indicating whether or not a thread belongs to the managed thread pool.

ManagedThreadId

获取当前托管线程的唯一标识符。Gets a unique identifier for the current managed thread.

Name

获取或设置线程的名称。Gets or sets the name of the thread.

Priority

获取或设置指示线程的调度优先级的值。Gets or sets a value indicating the scheduling priority of a thread.

ThreadState

获取一个值,该值包含当前线程的状态。Gets a value containing the states of the current thread.

方法

Abort()

在调用此方法的线程上引发 ThreadAbortException,以开始终止此线程的过程。Raises a ThreadAbortException in the thread on which it is invoked, to begin the process of terminating the thread. 调用此方法通常会终止线程。Calling this method usually terminates the thread.

Abort(Object)

引发在其上调用的线程中的 ThreadAbortException 以开始处理终止线程,同时提供有关线程终止的异常信息。Raises a ThreadAbortException in the thread on which it is invoked, to begin the process of terminating the thread while also providing exception information about the thread termination. 调用此方法通常会终止线程。Calling this method usually terminates the thread.

AllocateDataSlot()

在所有线程上分配未命名的数据槽。Allocates an unnamed data slot on all the threads. 为了获得更好的性能,请改用以 ThreadStaticAttribute 特性标记的字段。For better performance, use fields that are marked with the ThreadStaticAttribute attribute instead.

AllocateNamedDataSlot(String)

在所有线程上分配已命名的数据槽。Allocates a named data slot on all threads. 为了获得更好的性能,请改用以 ThreadStaticAttribute 特性标记的字段。For better performance, use fields that are marked with the ThreadStaticAttribute attribute instead.

BeginCriticalRegion()

通知宿主执行将要进入一个代码区域,在该代码区域内线程中止或未经处理异常的影响可能会危害应用程序域中的其他任务。Notifies a host that execution is about to enter a region of code in which the effects of a thread abort or unhandled exception might jeopardize other tasks in the application domain.

BeginThreadAffinity()

通知主机托管代码将要执行依赖于当前物理操作系统线程的标识的指令。Notifies a host that managed code is about to execute instructions that depend on the identity of the current physical operating system thread.

DisableComObjectEagerCleanup()

对于当前线程关闭运行时可调用包装 (RCW) 的自动清理。Turns off automatic cleanup of runtime callable wrappers (RCW) for the current thread.

EndCriticalRegion()

通知主机执行将要进入一个代码区域,在该代码区域内线程中止或未经处理异常的影响限于当前任务。Notifies a host that execution is about to enter a region of code in which the effects of a thread abort or unhandled exception are limited to the current task.

EndThreadAffinity()

通知主机托管代码已执行完依赖于当前物理操作系统线程的标识的指令。Notifies a host that managed code has finished executing instructions that depend on the identity of the current physical operating system thread.

Equals(Object)

确定指定的对象是否等于当前对象。Determines whether the specified object is equal to the current object.

(继承自 Object)
Finalize()

确保垃圾回收器回收 Thread 对象时释放资源并执行其他清理操作。Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the Thread object.

FreeNamedDataSlot(String)

为进程中的所有线程消除名称与槽之间的关联。Eliminates the association between a name and a slot, for all threads in the process. 为了获得更好的性能,请改用以 ThreadStaticAttribute 特性标记的字段。For better performance, use fields that are marked with the ThreadStaticAttribute attribute instead.

GetApartmentState()

返回表示单元状态的 ApartmentState 值。Returns an ApartmentState value indicating the apartment state.

GetCompressedStack()

返回 CompressedStack 对象,此对象可用于获取当前线程的堆栈。Returns a CompressedStack object that can be used to capture the stack for the current thread.

GetCurrentProcessorId()

获取用于指示当前线程正在哪个处理器上执行的 ID。Gets an ID used to indicate on which processor the current thread is executing.

GetData(LocalDataStoreSlot)

在当前线程的当前域中从当前线程上指定的槽中检索值。Retrieves the value from the specified slot on the current thread, within the current thread's current domain. 为了获得更好的性能,请改用以 ThreadStaticAttribute 特性标记的字段。For better performance, use fields that are marked with the ThreadStaticAttribute attribute instead.

GetDomain()

返回当前线程正在其中运行的当前域。Returns the current domain in which the current thread is running.

GetDomainID()

返回唯一的应用程序域标识符。Returns a unique application domain identifier.

GetHashCode()

返回当前线程的哈希代码。Returns a hash code for the current thread.

GetNamedDataSlot(String)

查找命名的数据槽。Looks up a named data slot. 为了获得更好的性能,请改用以 ThreadStaticAttribute 特性标记的字段。For better performance, use fields that are marked with the ThreadStaticAttribute attribute instead.

GetType()

获取当前实例的 TypeGets the Type of the current instance.

(继承自 Object)
Interrupt()

中断处于 WaitSleepJoin 线程状态的线程。Interrupts a thread that is in the WaitSleepJoin thread state.

Join()

在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止。Blocks the calling thread until the thread represented by this instance terminates, while continuing to perform standard COM and SendMessage pumping.

Join(Int32)

在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止或经过了指定时间为止。Blocks the calling thread until the thread represented by this instance terminates or the specified time elapses, while continuing to perform standard COM and SendMessage pumping.

Join(TimeSpan)

在继续执行标准的 COM 和 SendMessage 消息泵处理期间,阻止调用线程,直到由该实例表示的线程终止或经过了指定时间为止。Blocks the calling thread until the thread represented by this instance terminates or the specified time elapses, while continuing to perform standard COM and SendMessage pumping.

MemberwiseClone()

创建当前 Object 的浅表副本。Creates a shallow copy of the current Object.

(继承自 Object)
MemoryBarrier()

按如下方式同步内存访问:执行当前线程的处理器在对指令重新排序时,不能采用先执行 MemoryBarrier() 调用之后的内存存取,再执行 MemoryBarrier() 调用之前的内存存取的方式。Synchronizes memory access as follows: The processor executing the current thread cannot reorder instructions in such a way that memory accesses prior to the call to MemoryBarrier() execute after memory accesses that follow the call to MemoryBarrier().

ResetAbort()

取消当前线程所请求的 Abort(Object)Cancels an Abort(Object) requested for the current thread.

Resume()

继续已挂起的线程。Resumes a thread that has been suspended.

SetApartmentState(ApartmentState)

在线程启动前设置其单元状态。Sets the apartment state of a thread before it is started.

SetCompressedStack(CompressedStack)

将捕获的 CompressedStack 应用到当前线程。Applies a captured CompressedStack to the current thread.

SetData(LocalDataStoreSlot, Object)

在当前正在运行的线程上为此线程的当前域在指定槽中设置数据。Sets the data in the specified slot on the currently running thread, for that thread's current domain. 为了提高性能,请改用用 ThreadStaticAttribute 属性标记的字段。For better performance, use fields marked with the ThreadStaticAttribute attribute instead.

Sleep(Int32)

将当前线程挂起指定的毫秒数。Suspends the current thread for the specified number of milliseconds.

Sleep(TimeSpan)

将当前线程挂起指定的时间。Suspends the current thread for the specified amount of time.

SpinWait(Int32)

导致线程等待由 iterations 参数定义的时间量。Causes a thread to wait the number of times defined by the iterations parameter.

Start()

导致操作系统将当前实例的状态更改为 RunningCauses the operating system to change the state of the current instance to Running.

Start(Object)

导致操作系统将当前实例的状态更改为 Running,并选择提供包含线程执行的方法要使用的数据的对象。Causes the operating system to change the state of the current instance to Running, and optionally supplies an object containing data to be used by the method the thread executes.

Suspend()

挂起线程,或者如果线程已挂起,则不起作用。Either suspends the thread, or if the thread is already suspended, has no effect.

ToString()

返回一个表示当前对象的 string。Returns a string that represents the current object.

(继承自 Object)
TrySetApartmentState(ApartmentState)

在线程启动前设置其单元状态。Sets the apartment state of a thread before it is started.

VolatileRead(Byte)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(Double)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(Int16)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(Int32)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(Int64)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(IntPtr)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(Object)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(SByte)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(Single)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(UInt16)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(UInt32)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(UInt64)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileRead(UIntPtr)

读取字段值。Reads the value of a field. 无论处理器的数目或处理器缓存的状态如何,该值都是由计算机的任何处理器写入的最新值。The value is the latest written by any processor in a computer, regardless of the number of processors or the state of processor cache.

VolatileWrite(Byte, Byte)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(Double, Double)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(Int16, Int16)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(Int32, Int32)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(Int64, Int64)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(IntPtr, IntPtr)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(Object, Object)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(SByte, SByte)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(Single, Single)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(UInt16, UInt16)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(UInt32, UInt32)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(UInt64, UInt64)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

VolatileWrite(UIntPtr, UIntPtr)

立即向字段写入一个值,以使该值对计算机中的所有处理器都可见。Writes a value to a field immediately, so that the value is visible to all processors in the computer.

Yield()

导致调用线程执行准备好在当前处理器上运行的另一个线程。Causes the calling thread to yield execution to another thread that is ready to run on the current processor. 由操作系统选择要执行的线程。The operating system selects the thread to yield to.

显式界面实现

_Thread.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

将一组名称映射为对应的一组调度标识符。Maps a set of names to a corresponding set of dispatch identifiers.

_Thread.GetTypeInfo(UInt32, UInt32, IntPtr)

检索对象的类型信息,然后可以使用该信息获取接口的类型信息。Retrieves the type information for an object, which can then be used to get the type information for an interface.

_Thread.GetTypeInfoCount(UInt32)

检索对象提供的类型信息接口的数量(0 或 1)。Retrieves the number of type information interfaces that an object provides (either 0 or 1).

_Thread.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

提供对某一对象公开的属性和方法的访问。Provides access to properties and methods exposed by an object.

适用于

线程安全性

此类型是线程安全的。This type is thread safe.

另请参阅