Thread 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
建立並控制執行緒,設定優先順序,並取得其狀態。
public ref class Thread sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject
public ref class Thread sealed
public ref class Thread sealed : System::Runtime::InteropServices::_Thread
public ref class Thread sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject, System::Runtime::InteropServices::_Thread
public sealed class Thread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Thread
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
public sealed class Thread : System.Runtime.InteropServices._Thread
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
public sealed class Thread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.Runtime.InteropServices._Thread
type Thread = class
inherit CriticalFinalizerObject
[<System.Runtime.InteropServices.ComVisible(true)>]
type Thread = class
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
type Thread = class
interface _Thread
[<System.Runtime.InteropServices.ComVisible(true)>]
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
type Thread = class
inherit CriticalFinalizerObject
interface _Thread
Public NotInheritable Class Thread
Inherits CriticalFinalizerObject
Public NotInheritable Class Thread
Public NotInheritable Class Thread
Implements _Thread
Public NotInheritable Class Thread
Inherits CriticalFinalizerObject
Implements _Thread
- 繼承
- 繼承
-
Thread
- 屬性
- 實作
範例
下列範例示範簡單的線程功能。
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
此程式代碼會產生類似下列的輸出:
[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.
備註
類別 Thread 會建立及控制線程、設定其優先順序,並取得其狀態。
當進程啟動時,Common Language Runtime 會自動建立單一前景線程來執行應用程式程序代碼。 除了這個主要前景線程之外,進程也可以建立一或多個線程,以執行與進程相關聯的程序代碼部分。 這些線程可以在前景或背景中執行。 此外,您可以使用 類別 ThreadPool ,在 Common Language Runtime 所管理的背景工作線程上執行程序代碼。
啟動線程
要啟動執行緒,您需要在類別建構函式中提供委派,這個委派代表執行緒要執行的方法。 接著,您可以呼叫 Start 方法來開始執行。
建構子 Thread 可以採用兩種不同的委派類型,這取決於您是否可以將自變數傳遞至要執行的方法:
如果方法沒有自變數,您會將 ThreadStart 委派傳遞至建構函式。 它有簽章:
public delegate void ThreadStart()Public Delegate Sub ThreadStart()下列範例會建立並啟動執行 方法的
ExecuteInForeground線程。 方法會顯示某些線程屬性的相關信息,然後執行迴圈,在其中暫停半秒,並顯示經過的秒數。 當線程至少執行五秒時,迴圈會結束,而線程會終止執行。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() { 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 secondsopen 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 secondsImports 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如果方法有參數,您會將ParameterizedThreadStart委派傳遞給建構函式。 它有簽章:
public delegate void ParameterizedThreadStart(object obj)Public Delegate Sub ParameterizedThreadStart(obj As Object)委派所執行的方法接著可以在 C# 中強制轉換或在 Visual Basic 中轉換參數為適當的型別。
下列範例與上一個範例相同,不同之處在於它會呼叫 建 Thread(ParameterizedThreadStart) 構函式。 這個版本的
ExecuteInForeground方法具有單一參數,表示要執行循環的大約毫秒數。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; } 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 secondsopen 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 secondsImports 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
啟動Thread執行緒之後,就不需要保留對該物件的參考。 線程會繼續執行,直到線程程式完成為止。
擷取執行緒物件
您可以使用 static(Shared 在 Visual Basic 中)的 CurrentThread 屬性,從執行緒運行的程式碼中擷取到當前執行緒的參考。 下列範例使用 CurrentThread 屬性來顯示主要應用程式線程、另一個前景線程、背景線程和線程集區線程的相關信息。
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
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
前景執行緒與背景執行緒
類別的 Thread 實例代表前景線程或背景線程。 背景線程與前景線程相同,但有一個例外狀況:如果所有前景線程都已終止,背景線程不會讓進程繼續執行。 一旦停止所有前景線程,運行時間就會停止所有背景線程並關閉。
根據預設,下列線程會在前景執行:
主要應用程式線程。
呼叫類別建 Thread 構函式所建立的所有線程。
根據預設,下列線程會在背景執行:
執行環境維護的工作線程池中的線程。 您可以使用 ThreadPool 類別來設定線程集區,並在集區線程上排程工作。
Note
基於任務的異步操作會自動在執行緒集區的執行緒上執行。 以工作為基礎的異步作會使用 Task 和 Task<TResult> 類別來實作 以工作為基礎的異步模式。
從非托管程式碼進入托管執行環境的所有線程。
您可以隨時設定 IsBackground 屬性,以變更在背景中執行的線程。 背景執行緒適合用於任何在應用程式運行時應持續進行但不應妨礙應用程式終止的操作,如監控檔案系統變更或接收套接字連線。
下列範例說明前景和背景線程之間的差異。 就像啟動線程區段中的第 一個 範例一樣,不同之處在於它會在啟動線程之前,先在背景執行線程。 如輸出所示,迴圈會在執行五秒之前中斷。
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...
文化與線程
每個線程都有一個文化特性,由 CurrentCulture 屬性表示,而UI文化特性則以 CurrentUICulture 屬性表示。 目前的文化特性支援文化敏感的作業,例如剖析和格式化、字串比較和排序,同時也管理執行緒所使用的寫入系統和行事曆。 目前的UI文化提供資源文件中針對文化特性的資源檢索。
Important
CurrentCulture與目前線程以外的任何線程搭配使用時,和 CurrentUICulture 屬性無法可靠地運作。 如果執行緒嘗試在另一個執行緒上讀取或寫入這些屬性,就會拋出 An InvalidOperationException 。 我們建議您使用 CultureInfo.CurrentCulture 和 CultureInfo.CurrentUICulture 屬性來擷取和設定目前的文化特性。
具現化新線程時,其文化特性和UI文化特性是由目前的系統文化特性和UI文化特性所定義,而不是由建立新線程之線程的文化特性和UI文化特性所定義。 例如,如果目前的系統文化特性是英文(美國),而主要應用程式線程目前的文化特性是法文(法國),則從主線程呼叫 Thread(ParameterizedThreadStart) 建構函式所建立的新線程文化特性是英文(美國),而不是法文(法國)。 如需詳細資訊,請參閱類別主題的 CultureInfo 章節。
Important
這不適用於那些執行異步操作並且以 .NET Framework 4.6 和更新版本為目標的應用程式的線程。 在此情況下,文化特性和UI文化特性是異步作內容的一部分;異步作預設執行的線程會繼承啟動異步作的來源線程文化特性和UI文化特性。 如需詳細資訊,請參閱類別備註的「文化與基於任務的非同步操作」一節。
您可以執行下列任一項,以確保在應用程式中執行的所有線程共用相同的文化特性和 UI 文化特性:
您可以將代表該文化的 CultureInfo 對象傳遞給 ParameterizedThreadStart 委派或 ThreadPool.QueueUserWorkItem(WaitCallback, Object) 方法。
針對在 .NET Framework 4.5 和更新版本上執行的應用程式,您可以藉由設定 CultureInfo.DefaultThreadCurrentCulture 和 CultureInfo.DefaultThreadCurrentUICulture 屬性的值,來定義要指派給應用程式域中建立的所有線程的文化特性和 UI 文化特性。 請注意,這是個別應用程式域設定。
如需「文化和執行緒」的詳細資訊和範例,請參閱 CultureInfo 類別備註的一節。
取得與控制線程的相關信息
您可以擷取一些屬性值,以提供線程的相關信息。 在某些情況下,您也可以設定這些屬性值來控制線程的作業。 這些線程屬性包括:
名稱。 Name 是一個寫入一次屬性,可用來識別線程。 預設值為
null。哈希程序代碼,您可以藉由呼叫 GetHashCode 方法來擷取。 哈希程式代碼可用來唯一識別線程;在您線程的存留期內,其哈希程式代碼將不會與任何其他線程的值相衝突,不論您從中取得值的應用程式域為何。
線程標識碼。 運行時間會指派只讀 ManagedThreadId 屬性的值,並唯一識別其進程內的線程。
Note
作業系統的 ThreadId 與管理線程沒有固定的關聯性,因為非管理主機可以控制管理和非管理線程之間的關聯。 具體而言,先進的主機可以使用 CLR 裝載 API ,針對相同的作業系統執行緒排程許多受控執行緒,或在不同的作業系統執行緒之間移動受控執行緒。
線程的目前狀態。 在其存在期間,線程一律處於 屬性所 ThreadState 定義的一或多個狀態。
由ThreadPriority屬性定義的排程優先級別。 雖然您可以將此值設定為要求線程的優先順序,但作系統不保證會接受此值。
只讀 IsThreadPoolThread 屬性,指出線程是否為線程集區線程。
IsBackground 屬性。 如需詳細資訊,請參閱 前景和背景線程 一節。
建構函式
| 名稱 | Description |
|---|---|
| Thread(ParameterizedThreadStart, Int32) |
初始化類別的新實例 Thread ,指定一個代理,允許在執行緒啟動時傳遞物件,並指定執行緒的最大堆疊大小。 |
| Thread(ParameterizedThreadStart) |
初始化該類別的新實例 Thread ,指定一個代理,允許在執行緒啟動時傳遞物件給執行緒。 |
| Thread(ThreadStart, Int32) |
初始化該類別的新實例 Thread ,指定執行緒的最大堆疊大小。 |
| Thread(ThreadStart) |
初始化 Thread 類別的新執行個體。 |
屬性
| 名稱 | Description |
|---|---|
| ApartmentState |
已淘汰.
已淘汰.
取得或設定這個討論串的公寓狀態。 |
| CurrentContext |
取得執行緒目前執行的上下文。 |
| CurrentCulture |
取得或設定當前討論串的文化。 |
| CurrentPrincipal |
取得或設定執行緒目前的原則(用於基於角色的安全)。 |
| CurrentThread |
會取得目前執行的執行緒。 |
| CurrentUICulture |
取得或設定資源管理器目前使用的文化,以便在執行時查詢特定文化資源。 |
| ExecutionContext |
取得 ExecutionContext 一個包含當前執行緒各種上下文資訊的物件。 |
| IsAlive |
會獲得一個表示目前執行緒執行狀態的值。 |
| IsBackground |
取得或設定一個值,指示執行緒是否為背景執行緒。 |
| IsThreadPoolThread |
會取得一個值,表示執行緒是否屬於受管理的執行緒池。 |
| ManagedThreadId |
會獲得目前管理執行緒的唯一識別碼。 |
| Name |
取得或設定該串的名稱。 |
| Priority |
取得或設定一個值,表示執行緒的排程優先順序。 |
| ThreadState |
會得到包含當前執行緒狀態的值。 |
方法
| 名稱 | Description |
|---|---|
| Abort() |
已淘汰.
在被呼叫的執行緒中提出 a ThreadAbortException ,開始終止執行緒的過程。 呼叫此方法通常會終止執行緒。 |
| Abort(Object) |
已淘汰.
在呼叫執行緒中提出 a ThreadAbortException ,開始終止執行緒的過程,同時提供關於執行緒終止的例外資訊。 呼叫此方法通常會終止執行緒。 |
| AllocateDataSlot() |
在所有執行緒上分配一個未命名的資料槽。 為了提升效能,建議使用標有屬性的 ThreadStaticAttribute 欄位。 |
| AllocateNamedDataSlot(String) |
在所有執行緒上分配一個命名的資料槽。 為了提升效能,建議使用標有屬性的 ThreadStaticAttribute 欄位。 |
| BeginCriticalRegion() |
通知主機執行即將進入一個程式碼區域,該區域中執行緒中止或未處理異常可能危及應用程式領域中其他任務。 |
| BeginThreadAffinity() |
通知主機管理程式碼即將執行依賴當前實體作業系統執行緒身份的指令。 |
| DisableComObjectEagerCleanup() |
關閉目前執行緒執行時可呼叫包裝器(RCW)的自動清理。 |
| EndCriticalRegion() |
通知主機執行即將進入一個程式碼區域,該區域中執行緒中止或未處理異常的影響僅限於當前任務。 |
| EndThreadAffinity() |
通知主機管理程式碼已完成依據當前實體作業系統執行緒身份的指令執行。 |
| Equals(Object) |
判斷指定的物件是否等於目前的物件。 (繼承來源 Object) |
| Finalize() |
確保當垃圾回收器回收 Thread 物件時,資源會被釋放並執行其他清理作業。 |
| FreeNamedDataSlot(String) |
消除了所有執行緒中名稱與槽位之間的關聯。 為了提升效能,建議使用標有屬性的 ThreadStaticAttribute 欄位。 |
| GetApartmentState() |
回傳 ApartmentState 一個表示公寓狀態的數值。 |
| GetCompressedStack() |
已淘汰.
已淘汰.
回傳一個 CompressedStack 物件,可用來擷取當前執行緒的堆疊。 |
| GetCurrentProcessorId() |
會取得一個 ID,用來表示目前執行緒正在哪個處理器上執行。 |
| GetData(LocalDataStoreSlot) |
從目前執行緒的指定欄位中擷取該值,該欄位位於目前執行緒的當前域內。 為了提升效能,建議使用標有屬性的 ThreadStaticAttribute 欄位。 |
| GetDomain() |
回傳目前執行緒正在運行的網域。 |
| GetDomainID() |
回傳唯一的應用程式領域識別碼。 |
| GetHashCode() |
回傳當前執行緒的雜湊碼。 |
| GetHashCode() |
做為預設哈希函式。 (繼承來源 Object) |
| GetNamedDataSlot(String) |
查一個有名的資料槽。 為了提升效能,建議使用標有屬性的 ThreadStaticAttribute 欄位。 |
| GetType() |
取得目前實例的 Type。 (繼承來源 Object) |
| Interrupt() |
中斷處於 WaitSleepJoin 執行緒狀態的執行緒。 |
| Join() |
阻塞呼叫執行緒,直到該執行緒終止,同時繼續執行標準 COM 與 |
| Join(Int32) |
在執行標準 COM 與 SendMessage 泵送前,阻塞呼叫執行緒直到該執行緒終止或指定時間結束。 |
| Join(TimeSpan) |
在執行標準 COM 與 SendMessage 泵送前,阻塞呼叫執行緒直到該執行緒終止或指定時間結束。 |
| MemberwiseClone() |
建立目前 Object的淺層複本。 (繼承來源 Object) |
| MemoryBarrier() |
記憶體存取的同步方式如下:執行當前執行緒的處理器無法以一種方式重新排序指令,使得記憶體在呼叫執行 MemoryBarrier() 前存取,而記憶體存取則是在呼叫執行後的記憶體存取 MemoryBarrier()之後進行。 |
| ResetAbort() |
已淘汰.
取消 Abort(Object) 了目前討論串的請求。 |
| Resume() |
已淘汰.
已淘汰.
已淘汰.
恢復一個已暫停的討論串。 |
| SetApartmentState(ApartmentState) |
在執行緒啟動前就設定了 apartment 狀態。 |
| SetCompressedStack(CompressedStack) |
已淘汰.
已淘汰.
將捕獲 CompressedStack 的執行緒套用到目前執行緒。 |
| SetData(LocalDataStoreSlot, Object) |
將資料設在目前執行緒的指定槽位,對應該執行緒目前的網域。 為了提升效能,建議使用標示為 屬性 ThreadStaticAttribute 的欄位。 |
| Sleep(Int32) |
暫停目前執行緒指定毫秒數。 |
| Sleep(TimeSpan) |
暫停目前執行緒指定時間。 |
| SpinWait(Int32) |
會讓執行緒等待參數定義 |
| Start() |
導致作業系統將目前實例的狀態變更為 Running。 |
| Start(Object) |
會讓作業系統將目前實例的狀態變更為 Running,並可選擇性地提供一個物件,包含執行緒執行的方法所使用的資料。 |
| Suspend() |
已淘汰.
已淘汰.
已淘汰.
要麼暫停執行緒,要麼如果執行緒已經暫停,則不產生影響。 |
| ToString() |
傳回表示目前 物件的字串。 (繼承來源 Object) |
| TrySetApartmentState(ApartmentState) |
在執行緒啟動前就設定了 apartment 狀態。 |
| UnsafeStart() |
導致作業系統將目前實例的狀態變更為 Running。 |
| UnsafeStart(Object) |
會讓作業系統將目前實例的狀態變更為 Running,並可選擇性地提供一個物件,包含執行緒執行的方法所使用的資料。 |
| VolatileRead(Byte) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(Double) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(Int16) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(Int32) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(Int64) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(IntPtr) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(Object) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(SByte) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(Single) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(UInt16) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(UInt32) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(UInt64) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileRead(UIntPtr) |
已淘汰.
讀取欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若程式碼中在此方法之後出現讀取或寫入,處理器無法在此方法之前移動該操作。 |
| VolatileWrite(Byte, Byte) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(Double, Double) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(Int16, Int16) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(Int32, Int32) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(Int64, Int64) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(IntPtr, IntPtr) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(Object, Object) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(SByte, SByte) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(Single, Single) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(UInt16, UInt16) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(UInt32, UInt32) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(UInt64, UInt64) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| VolatileWrite(UIntPtr, UIntPtr) |
已淘汰.
寫入欄位的值。 在需要此方法的系統中,會插入一個記憶體屏障,阻止處理器重新排序記憶體操作如下:若讀取或寫入出現在此方法之前,處理器無法在此方法後移動該操作。 |
| Yield() |
導致呼叫執行緒的執行讓位給在目前處理器上準備執行的其他執行緒。 作業系統會選擇要讓路的執行緒。 |
明確介面實作
| 名稱 | Description |
|---|---|
| _Thread.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) |
將一組名稱對應至一組對應的分派識別項 (Dispatch Identifier)。 |
| _Thread.GetTypeInfo(UInt32, UInt32, IntPtr) |
擷取物件的類型資訊,可以用來取得介面的類型資訊。 |
| _Thread.GetTypeInfoCount(UInt32) |
擷取物件提供的類型資訊介面數目 (0 或 1)。 |
| _Thread.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) |
提供物件所公開屬性和方法的存取權。 |
適用於
執行緒安全性
此類型是安全線程。