共用方式為


建立執行緒並在啟動時間傳遞資料

更新:2007 年 11 月

當建立作業系統處理序時,作業系統會插入執行緒以在該處理序中執行程式碼,包括任何原始應用程式定義域。從該處,可建立及終結應用程式定義域,而不一定需要建立及終結任何作業系統執行緒。如果正在執行的是 Managed 程式碼,則可藉由擷取 Thread 型別的靜態 CurrentThread 屬性,獲得現行應用程式定義域中正在執行的執行緒之 Thread 物件。本主題將說明執行緒的建立,並討論將資料傳遞給執行緒程序的替代方案。

建立執行緒

建立新的 Thread 物件時,新的 Managed 執行緒也會隨之建立。Thread 類別具有會採用 ThreadStart 委派或 ParameterizedThreadStart 委派的建構函式;當您呼叫 Start 方法時,委派會包裝新執行緒所叫用的方法。多次呼叫 Start 會擲回 ThreadStateException

通常在新執行緒實際啟動之前,會立即傳回 Start 方法。您隨時都可以使用 ThreadStateIsAlive 屬性來決定執行緒的狀態,但絕不能使用這些屬性來同步處理執行緒的活動。

注意事項:

一旦執行緒啟動之後,便不需要保留 Thread 物件的參考。此執行緒會繼續執行,一直到執行緒的程序結束為止。

下列程式碼範例建立兩個新執行緒,以在另一個物件上呼叫執行個體及靜態方法。

Imports System
Imports System.Threading

Public Class ServerClass

    ' The method that will be called when the thread is started.
    Public Sub InstanceMethod()
        Console.WriteLine( _
            "ServerClass.InstanceMethod is running on another thread.")

        ' Pause for a moment to provide a delay to make 
        ' threads more apparent.
        Thread.Sleep(3000) 
        Console.WriteLine( _
            "The instance method called by the worker thread has ended.")
    End Sub 'InstanceMethod

    Public Shared Sub StaticMethod()
        Console.WriteLine( _
            "ServerClass.StaticMethod is running on another thread.")

        ' Pause for a moment to provide a delay to make 
        ' threads more apparent.
        Thread.Sleep(5000) 
        Console.WriteLine( _
            "The static method called by the worker thread has ended.")
    End Sub 'StaticMethod
End Class 'ServerClass

Public Class Simple

    Public Shared Sub Main() 
        Console.WriteLine("Thread Simple Sample")

        Dim serverObject As New ServerClass()

        ' Create the thread object, passing in the 
        ' serverObject.InstanceMethod method using a
        ' ThreadStart delegate.
        Dim InstanceCaller As New Thread( _
            New ThreadStart(AddressOf serverObject.InstanceMethod))

        ' Start the thread.
        InstanceCaller.Start()

        Console.WriteLine("The Main() thread calls this after " _
            & "starting the new InstanceCaller thread.")

        ' Create the thread object, passing in the 
        ' serverObject.StaticMethod method using a 
        ' ThreadStart delegate.
        Dim StaticCaller As New Thread( _
            New ThreadStart(AddressOf ServerClass.StaticMethod))

        ' Start the thread.
        StaticCaller.Start()

        Console.WriteLine("The Main() thread calls this after " _
            & "starting the new StaticCaller thread.")

    End Sub 'Main
End Class 'Simple
using System;
using System.Threading;

public class ServerClass
{
    // The method that will be called when the thread is started.
    public void InstanceMethod()
    {
        Console.WriteLine(
            "ServerClass.InstanceMethod is running on another thread.");

        // Pause for a moment to provide a delay to make 
        // threads more apparent.
        Thread.Sleep(3000);
        Console.WriteLine(
            "The instance method called by the worker thread has ended.");
    }

    public static void StaticMethod()
    {
        Console.WriteLine(
            "ServerClass.StaticMethod is running on another thread.");

        // Pause for a moment to provide a delay to make 
        // threads more apparent.
        Thread.Sleep(5000);
        Console.WriteLine(
            "The static method called by the worker thread has ended.");
    }
}

public class Simple{
    public static int Main(String[] args)
    {
        Console.WriteLine("Thread Simple Sample");

        ServerClass serverObject = new ServerClass();

        // Create the thread object, passing in the 
        // serverObject.InstanceMethod method using a 
        // ThreadStart delegate.
        Thread InstanceCaller = new Thread(
            new ThreadStart(serverObject.InstanceMethod));

        // Start the thread.
        InstanceCaller.Start();

        Console.WriteLine("The Main() thread calls this after " 
            + "starting the new InstanceCaller thread.");

        // Create the thread object, passing in the 
        // serverObject.StaticMethod method using a 
        // ThreadStart delegate.
        Thread StaticCaller = new Thread(
            new ThreadStart(ServerClass.StaticMethod));

        // Start the thread.
        StaticCaller.Start();

        Console.WriteLine("The Main() thread calls this after "
            + "starting the new StaticCaller thread.");

        return 0;
    }
}
using namespace System;
using namespace System::Threading;

public ref class ServerClass
{
public:

    // The method that will be called when the thread is started.
    void InstanceMethod()
    {
        Console::WriteLine(
            "ServerClass->InstanceMethod is running on another thread.");

        // Pause for a moment to provide a delay to make 
        // threads more apparent.
        Thread::Sleep(3000);
        Console::WriteLine(
            "The instance method called by the worker thread has ended.");
    }

    static void StaticMethod()
    {
        Console::WriteLine(
            "ServerClass::StaticMethod is running on another thread.");

        // Pause for a moment to provide a delay to make 
        // threads more apparent.
        Thread::Sleep(5000);
        Console::WriteLine(
            "The static method called by the worker thread has ended.");
    }
};

void main()
{
    Console::WriteLine("Thread Simple Sample");

    ServerClass^ serverObject = gcnew ServerClass();

    // Create the thread object, passing in a ThreadStart delegate
    // representing an instance of ServerClass and the 
    // ServerClass::InstanceMethod method.
    Thread^ InstanceCaller = gcnew Thread(
        gcnew ThreadStart(serverObject, &ServerClass::InstanceMethod));

    // Start the thread.
    InstanceCaller->Start();

    Console::WriteLine("The main thread has " 
        + "started the new InstanceMethod thread.");

    // Create the thread object, passing in a ThreadStart delegate 
    // representing the static ServerClass::StaticMethod method.
    Thread^ StaticCaller = gcnew Thread(
        gcnew ThreadStart(&ServerClass::StaticMethod));

    // Start the thread.
    StaticCaller->Start();

    Console::WriteLine("The main thread has called "
        + "the new StaticMethod thread.");
}

將資料傳遞給執行緒以及擷取來自執行緒的資料

在 .NET Framework 2.0 版中,當您呼叫 Thread.Start 方法多載時,ParameterizedThreadStart 委派可讓您輕鬆地將含有資料的物件傳遞給執行緒。如需程式碼範例,請參閱 ParameterizedThreadStart

使用 ParameterizedThreadStart 委派並不是傳遞資料的型別安全方式,因為 Thread.Start 方法多載會接受任何物件。替代方案是在 Helper 類別中封裝執行緒程序和資料,並使用 ThreadStart 委派來執行執行緒程序。下列兩個程式碼範例將會示範這項技術。

這些委派都不具有傳回值,因為沒有地方可供傳回來自非同步呼叫的資料。若要擷取執行緒方法的結果,可以依照第二個程式碼範例所示,使用回呼 (Callback) 方法。

Imports System
Imports System.Threading

' The ThreadWithState class contains the information needed for
' a task, and the method that executes the task.
'
Public Class ThreadWithState
    ' State information used in the task.
    Private boilerplate As String
    Private value As Integer

    ' The constructor obtains the state information.
    Public Sub New(ByVal text As String, ByVal number As Integer)
        boilerplate = text
        value = number
    End Sub

    ' The thread procedure performs the task, such as formatting 
    ' and printing a document.
    Public Sub ThreadProc()
        Console.WriteLine(boilerplate, value) 
    End Sub
End Class

' Entry point for the example.
'
Public Class Example
    Public Shared Sub Main()

        ' Supply the state information required by the task.
        Dim tws As New ThreadWithState( _
            "This report displays the number {0}.", 42)

        ' Create a thread to execute the task, and then
        ' start the thread.
        Dim t As New Thread(AddressOf tws.ThreadProc)
        t.Start()
        Console.WriteLine("Main thread does some work, then waits.")
        t.Join()
        Console.WriteLine( _
            "Independent task has completed; main thread ends.")  
    End Sub
End Class
using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, and the method that executes the task.
//
public class ThreadWithState {
    // State information used in the task.
    private string boilerplate;
    private int value;

    // The constructor obtains the state information.
    public ThreadWithState(string text, int number) 
    {
        boilerplate = text;
        value = number;
    }

    // The thread procedure performs the task, such as formatting 
    // and printing a document.
    public void ThreadProc() 
    {
        Console.WriteLine(boilerplate, value); 
    }
}

// Entry point for the example.
//
public class Example {
    public static void Main() 
    {
        // Supply the state information required by the task.
        ThreadWithState tws = new ThreadWithState(
            "This report displays the number {0}.", 42);

        // Create a thread to execute the task, and then
        // start the thread.
        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
        t.Start();
        Console.WriteLine("Main thread does some work, then waits.");
        t.Join();
        Console.WriteLine(
            "Independent task has completed; main thread ends.");  
    }
}
using namespace System;
using namespace System::Threading;

// The ThreadWithState class contains the information needed for
// a task, and the method that executes the task.
//
public ref class ThreadWithState 
{
private:
    // State information used in the task.
    String^ boilerplate;
    int value;

public:
    // The constructor obtains the state information.
    ThreadWithState(String^ text, int number) 
    {
        boilerplate = text;
        value = number;
    }

    // The thread procedure performs the task, such as formatting 
    // and printing a document.
    void ThreadProc() 
    {
        Console::WriteLine(boilerplate, value); 
    }
};

// Entry point for the example.
//
void main() 
{
    // Supply the state information required by the task.
    ThreadWithState^ tws = gcnew ThreadWithState(
        "This report displays the number {0}.", 42);

    // Create a thread to execute the task, and then
    // start the thread.
    Thread^ t = gcnew Thread(
        gcnew ThreadStart(tws, &ThreadWithState::ThreadProc));
    t->Start();
    Console::WriteLine("Main thread does some work, then waits.");
    t->Join();
    Console::WriteLine(
        "Independent task has completed; main thread ends.");  
}

使用回呼方法擷取資料

下列範例示範回呼 (Callback) 方法,它會從執行緒擷取資料。類別的建構函式 (Constructor) 包含資料和執行緒方法,它也接受代表回呼方法的委派;在執行緒方法結束之前,它會叫用 (Invoke) 回呼委派。

Imports System
Imports System.Threading

' The ThreadWithState class contains the information needed for
' a task, the method that executes the task, and a delegate
' to call when the task is complete.
'
Public Class ThreadWithState
    ' State information used in the task.
    Private boilerplate As String
    Private value As Integer

    ' Delegate used to execute the callback method when the
    ' task is complete.
    Private callback As ExampleCallback

    ' The constructor obtains the state information and the
    ' callback delegate.
    Public Sub New(ByVal text As String, ByVal number As Integer, _
                   ByVal callbackDelegate As ExampleCallback)
        boilerplate = text
        value = number
        callback = callbackDelegate
    End Sub

    ' The thread procedure performs the task, such as
    ' formatting and printing a document, and then invokes
    ' the callback delegate with the number of lines printed.
    Public Sub ThreadProc()
        Console.WriteLine(boilerplate, value) 
        If Not callback Is Nothing Then callback(1)
    End Sub
End Class

' Delegate that defines the signature for the callback method.
'
Public Delegate Sub ExampleCallback(ByVal lineCount As Integer)

' Entry point for the example.
'
Public Class Example
    Public Shared Sub Main()
        ' Supply the state information required by the task.
        Dim tws As New ThreadWithState( _
            "This report displays the number {0}.", _
            42, _
            New ExampleCallback(AddressOf ResultCallback) _
        )

        Dim t As New Thread(AddressOf tws.ThreadProc)
        t.Start()
        Console.WriteLine("Main thread does some work, then waits.")
        t.Join()
        Console.WriteLine( _
            "Independent task has completed; main thread ends.")  
    End Sub

    ' The callback method must match the signature of the
    ' callback delegate.
    '
    Public Shared Sub ResultCallback(ByVal lineCount As Integer)
        Console.WriteLine("Independent task printed {0} lines.", _
            lineCount)  
    End Sub
End Class
using System;
using System.Threading;

// The ThreadWithState class contains the information needed for
// a task, the method that executes the task, and a delegate
// to call when the task is complete.
//
public class ThreadWithState {
    // State information used in the task.
    private string boilerplate;
    private int value;

    // Delegate used to execute the callback method when the
    // task is complete.
    private ExampleCallback callback;

    // The constructor obtains the state information and the
    // callback delegate.
    public ThreadWithState(string text, int number, 
        ExampleCallback callbackDelegate) 
    {
        boilerplate = text;
        value = number;
        callback = callbackDelegate;
    }
    
    // The thread procedure performs the task, such as
    // formatting and printing a document, and then invokes
    // the callback delegate with the number of lines printed.
    public void ThreadProc() 
    {
        Console.WriteLine(boilerplate, value);
        if (callback != null)
            callback(1);
    }
}

// Delegate that defines the signature for the callback method.
//
public delegate void ExampleCallback(int lineCount);

// Entry point for the example.
//
public class Example 
{
    public static void Main() 
    {
        // Supply the state information required by the task.
        ThreadWithState tws = new ThreadWithState(
            "This report displays the number {0}.",
            42,
            new ExampleCallback(ResultCallback)
        );

        Thread t = new Thread(new ThreadStart(tws.ThreadProc));
        t.Start();
        Console.WriteLine("Main thread does some work, then waits.");
        t.Join();
        Console.WriteLine(
            "Independent task has completed; main thread ends."); 
    }

    // The callback method must match the signature of the
    // callback delegate.
    //
    public static void ResultCallback(int lineCount) 
    {
        Console.WriteLine(
            "Independent task printed {0} lines.", lineCount);
    }
}
using namespace System;
using namespace System::Threading;

// Delegate that defines the signature for the callback method.
//
public delegate void ExampleCallback(int lineCount);

// The ThreadWithState class contains the information needed for
// a task, the method that executes the task, and a delegate
// to call when the task is complete.
//
public ref class ThreadWithState 
{
private:
    // State information used in the task.
    String^ boilerplate;
    int value;

    // Delegate used to execute the callback method when the
    // task is complete.
    ExampleCallback^ callback;

public:
    // The constructor obtains the state information and the
    // callback delegate.
    ThreadWithState(String^ text, int number, 
        ExampleCallback^ callbackDelegate)  
    {
        boilerplate = text;
        value = number;
        callback = callbackDelegate;
    }

    // The thread procedure performs the task, such as
    // formatting and printing a document, and then invokes
    // the callback delegate with the number of lines printed.
    void ThreadProc() 
    {
        Console::WriteLine(boilerplate, value); 
        if (callback != nullptr)
            callback(1);
    }
};

public ref class Example
{
public:
    static void Demo()
    {
        // Supply the state information required by the task.
        ThreadWithState^ tws = gcnew ThreadWithState(
            "This report displays the number {0}.",
            42,
            gcnew ExampleCallback(&Example::ResultCallback)
        );

        // Create a thread to execute the task, and then
        // start the thread.
        Thread^ t = gcnew Thread(
            gcnew ThreadStart(tws, &ThreadWithState::ThreadProc));
        t->Start();
        Console::WriteLine("Main thread does some work, then waits.");
        t->Join();
        Console::WriteLine(
            "Independent task has completed; main thread ends.");  
    }

private:
    // The callback method must match the signature of the
    // callback delegate.
    //
    static void ResultCallback(int lineCount) 
    {
        Console::WriteLine(
            "Independent task printed {0} lines.", lineCount);
    }
};

// Entry point for the example.
//
void main() 
{
    Example::Demo();
}

請參閱

參考

Thread

ThreadStart

ParameterizedThreadStart

Thread.Start

其他資源

Managed 執行緒

使用執行緒和執行緒處理