System.Threading.Thread 類別
本文提供此 API 參考文件的補充備註。
類別 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 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
如果方法有 自變數,您會將委派傳遞 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 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
啟動線程之後,就不需要保留對象的參考 Thread 。 線程會繼續執行,直到線程程式完成為止。
擷取 Thread 物件
您可以使用 static (Shared
在 Visual Basic 中) CurrentThread 屬性,從線程執行的程式代碼擷取目前執行線程的參考。 下列範例使用 CurrentThread 屬性來顯示主要應用程式線程、另一個前景線程、背景線程和線程集區線程的相關信息。
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
前景和背景執行緒
類別的 Thread 實例代表前景線程或背景線程。 背景線程與前景線程相同,但有一個例外狀況:如果所有前景線程都已終止,背景線程不會讓進程繼續執行。 一旦停止所有前景線程,運行時間就會停止所有背景線程並關閉。
根據預設,下列線程會在前景執行:
主要應用程式線程。
呼叫類別建 Thread 構函式所建立的所有線程。
根據預設,下列線程會在背景執行:
線程集區線程,其來自運行時間所維護的背景工作線程集區。 您可以使用 類別,在線程集區線程 ThreadPool 上設定線程集區並排程工作。
注意
以工作為基礎的異步操作會自動在線程集區線程上執行。 以工作為基礎的異步操作會使用 Task 和 Task<TResult> 類別來實 作以工作為基礎的異步模式。
從 Unmanaged 程式代碼進入 Managed 執行環境的所有線程。
您可以隨時設定 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文化特性提供資源文件中資源區分文化特性的擷取。
重要
CurrentCulture與目前線程以外的任何線程搭配使用時,和 CurrentUICulture 屬性無法可靠地運作。 在 .NET Framework 中,讀取這些屬性是可靠的,不過為目前線程以外的線程設定這些屬性不是。 在 .NET Core 上,如果線程嘗試在不同的線程上讀取或寫入這些屬性, InvalidOperationException 則會擲回 。 我們建議您使用 CultureInfo.CurrentCulture 和 CultureInfo.CurrentUICulture 屬性來擷取和設定目前的文化特性。
具現化新線程時,其文化特性和UI文化特性是由目前的系統文化特性和UI文化特性所定義,而不是由建立新線程之線程的文化特性和UI文化特性所定義。 例如,如果目前的系統文化特性是英文(美國),而主要應用程式線程目前的文化特性是法文(法國),則從主線程呼叫Thread(ParameterizedThreadStart)建構函式所建立的新線程文化特性為英文(美國),而不是法文(法國)。 如需詳細資訊,請參閱類別主題的 CultureInfo 一節。
重要
這不是針對以 .NET Framework 4.6 和更新版本為目標之應用程式執行異步操作的線程。 在此情況下,文化特性和UI文化特性是異步操作內容的一部分;異步操作預設執行的線程會繼承啟動異步操作的來源線程文化特性和UI文化特性。 如需詳細資訊,請參閱類別備註的 CultureInfo 一節。
您可以執行下列任一項,以確保在應用程式中執行的所有線程共用相同的文化特性和 UI 文化特性:
您可以將代表該文化特性的對象傳遞 CultureInfo 至 ParameterizedThreadStart 委派或 ThreadPool.QueueUserWorkItem(WaitCallback, Object) 方法。
針對在 .NET Framework 4.5 和更新版本上執行的應用程式,您可以藉由設定 和 屬性的值 CultureInfo.DefaultThreadCurrentCulture ,定義要指派給應用程式域中建立的所有線程的文化特性和 CultureInfo.DefaultThreadCurrentUICulture UI 文化特性。 請注意,這是個別應用程式域設定。
如需詳細資訊和範例,請參閱類別備註的 CultureInfo 一節。
取得與控制線程的相關信息
您可以擷取一些屬性值,以提供線程的相關信息。 在某些情況下,您也可以設定這些屬性值來控制線程的作業。 這些線程屬性包括:
名稱。 Name 是一個寫入一次屬性,可用來識別線程。 其預設值為
null
。哈希程序代碼,您可以藉由呼叫 GetHashCode 方法來擷取。 哈希程式代碼可用來唯一識別線程;在您線程的存留期內,其哈希程式代碼將不會與任何其他線程的值相衝突,不論您從中取得值的應用程式域為何。
線程標識碼。 運行時間會指派只讀 ManagedThreadId 屬性的值,並唯一識別其進程內的線程。
線程的目前狀態。 在其存在期間,線程一律處於 屬性所 ThreadState 定義的一或多個狀態。
屬性所 ThreadPriority 定義的排程優先順序。 雖然您可以將此值設定為要求線程的優先順序,但操作系統不保證會接受此值。
只讀 IsThreadPoolThread 屬性,指出線程是否為線程集區線程。
IsBackground 屬性。 如需詳細資訊,請參閱 前景和背景線程 一節。
範例
下列範例示範簡單的線程功能。
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.