Freigeben über


Erstellen von Threads und Übergeben von Daten zur Startzeit

Aktualisiert: November 2007

Beim Erstellen eines Prozesses im Betriebssystem wird ein Thread eingeschleust, um Code in diesem Prozess auszuführen, einschließlich jeder ursprünglichen Anwendungsdomäne. Ab diesem Zeitpunkt können Anwendungsdomänen erstellt und gelöscht werden, ohne dass Betriebssystemthreads erstellt oder gelöscht werden müssen. Bei verwaltetem ausgeführtem Code kann ein Thread-Objekt für den in der aktuellen Anwendungsdomäne ausführenden Thread abgerufen werden. Dies erfolgt durch Abruf der statischen CurrentThread-Eigenschaft vom Typ Thread. In diesem Thema wird die Threaderstellung beschrieben, und es werden Alternativen zur Übergabe von Daten an die Threadprozedur erläutert.

Erstellen eines Threads

Beim Erstellen eines neuen Thread-Objekts wird ein neuer verwalteter Thread erstellt. Die Thread-Klasse verfügt über Konstruktoren, die einen ThreadStart-Delegaten oder einen ParameterizedThreadStart-Delegaten akzeptieren. Der Delegat schließt die Methode ein, die beim Aufrufen der Start-Methode vom neuen Thread aufgerufen wird. Das mehrfache Aufrufen von Start hat zur Folge, dass ThreadStateException ausgelöst wird.

Die Start-Methode wird sofort beendet. Häufig geschieht dies, bevor die Ausführung des neuen Threads gestartet wurde. Sie können die ThreadState-Eigenschaft oder die IsAlive-Eigenschaft verwenden, um den Zustand des Threads jederzeit zu bestimmen. Diese Eigenschaften sollten jedoch grundsätzlich nicht dazu verwendet werden, die Aktivitäten der Threads zu synchronisieren.

Hinweis:

Sobald ein Thread gestartet wird, ist es nicht notwendig, einen Verweis auf das Thread-Objekt beizubehalten. Der Thread wird bis zum Ende der Threadprozedur fortgesetzt.

Im folgenden Codebeispiel werden zwei neue Threads erstellt, um Instanz- und statische Methoden für ein anderes Objekt aufzurufen.

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.");
}

Übergeben von Daten an Threads und Abrufen von Daten aus Threads

In .NET Framework, Version 2.0, bietet der ParameterizedThreadStart-Delegat ein einfaches Verfahren zur Übergabe eines Objekts mit Daten an einen Thread, sobald die Überladung der Thread.Start-Methode aufgerufen wird. Ein Codebeispiel finden Sie unter ParameterizedThreadStart.

Die Verwendung des ParameterizedThreadStart-Delegaten ist kein typsicheres Verfahren zur Übergabe von Daten, da die Überladung der Thread.Start-Methode beliebige Objekte akzeptiert. Eine Alternative besteht darin, die Threadprozedur und die Daten in einer Hilfsklasse einzukapseln und die Threadprozedur mit dem ThreadStart-Delegaten auszuführen. Dieses Verfahren wird in den folgenden beiden Codebeispielen veranschaulicht.

Keiner dieser Delegaten verfügt über einen Rückgabewert, da die Rückgabe der Daten aus einem asynchronen Aufruf nicht vorgesehen ist. Um die Ergebnisse einer Threadmethode abzurufen, können Sie eine Rückrufmethode verwenden (siehe zweites Codebeispiel).

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.");  
}

Abrufen von Daten mit Rückrufmethoden

Im folgenden Beispiel wird eine Rückrufmethode dargestellt, die Daten aus einem Thread abruft. Der Konstruktor für die Klasse, der die Daten und die Threadmethode enthält, akzeptiert auch einen Delegaten, der die Rückrufmethode darstellt. Vor dem Ende der Threadmethode ruft er den Rückrufdelegaten auf.

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

Siehe auch

Referenz

Thread

ThreadStart

ParameterizedThreadStart

Thread.Start

Weitere Ressourcen

Verwaltetes Threading

Verwenden von Threads und Threading