本文提供此 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 ({Thread.CurrentThread.ManagedThreadId}) exiting..."); } 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 {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000.0:N2} seconds"); 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 ({Thread.CurrentThread.ManagedThreadId}) exiting..."); } 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 {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000.0:N2} seconds"); 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執行緒之後,就不需要保留對該物件的參考。 線程會繼續執行,直到線程程式完成為止。
擷取執行緒物件
您可以使用 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 #{th.ManagedThreadId}: ");
Console.WriteLine($" Background thread: {th.IsBackground}");
Console.WriteLine($" Thread pool thread: {th.IsThreadPoolThread}");
Console.WriteLine($" Priority: {th.Priority}");
Console.WriteLine($" Culture: {th.CurrentCulture.Name}");
Console.WriteLine($" UI culture: {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> 類別來實作 以工作為基礎的異步模式。
從非托管程式碼進入托管執行環境的所有線程。
您可以隨時設定 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 ({Thread.CurrentThread.ManagedThreadId}) exiting...");
}
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 {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000.0:N2} seconds");
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文化特性。 如需詳細資訊,請參閱類別備註的「文化與基於任務的非同步操作」一節。
您可以執行下列任一項,以確保在應用程式中執行的所有線程共用相同的文化特性和 UI 文化特性:
您可以將代表該文化的 CultureInfo 對象傳遞給 ParameterizedThreadStart 委派或 ThreadPool.QueueUserWorkItem(WaitCallback, Object) 方法。
針對在 .NET Framework 4.5 和更新版本上執行的應用程式,您可以藉由設定 CultureInfo.DefaultThreadCurrentCulture 和 CultureInfo.DefaultThreadCurrentUICulture 屬性的值,來定義要指派給應用程式域中建立的所有線程的文化特性和 UI 文化特性。 請注意,這是個別應用程式域設定。
如需「文化和執行緒」的詳細資訊和範例,請參閱 CultureInfo 類別備註的一節。
取得與控制線程的相關信息
您可以擷取一些屬性值,以提供線程的相關信息。 在某些情況下,您也可以設定這些屬性值來控制線程的作業。 這些線程屬性包括:
名稱。 Name 是一個寫入一次屬性,可用來識別線程。 預設值為
null
。哈希程序代碼,您可以藉由呼叫 GetHashCode 方法來擷取。 哈希程式代碼可用來唯一識別線程;在您線程的存留期內,其哈希程式代碼將不會與任何其他線程的值相衝突,不論您從中取得值的應用程式域為何。
線程標識碼。 運行時間會指派只讀 ManagedThreadId 屬性的值,並唯一識別其進程內的線程。
備註
作業系統的 ThreadId 與管理線程沒有固定的關聯性,因為非管理主機可以控制管理和非管理線程之間的關聯。 具體而言,先進的主機可以使用 CLR 裝載 API ,針對相同的作業系統執行緒排程許多受控執行緒,或在不同的作業系統執行緒之間移動受控執行緒。
線程的目前狀態。 在其存在期間,線程一律處於 屬性所 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: {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.