다음을 통해 공유


스레드 만들기 및 시작 시 데이터 전달

운영 체제 프로세스가 만들어지면 운영 체제는 원래 애플리케이션 도메인을 포함하여 해당 프로세스에서 코드를 실행하는 스레드를 삽입합니다. 이 시점부터는 운영 체제 스레드를 반드시 만들거나 제거하지 않고도 애플리케이션 도메인을 만들고 제거할 수 있습니다. 실행 중인 코드가 관리 코드 Thread 인 경우 형식CurrentThread의 정적 Thread 속성을 검색하여 현재 애플리케이션 도메인에서 실행되는 스레드에 대한 개체를 가져올 수 있습니다. 이 항목에서는 스레드 생성에 대해 설명하고 스레드 프로시저에 데이터를 전달하는 대안에 대해 설명합니다.

스레드 만들기

Thread 개체를 만들면 관리되는 새 스레드가 만들어집니다. 클래스에는 Thread 대리자 또는 ThreadStart 대리자를 사용하는 생성자가 있으며, 이 대리자는 ParameterizedThreadStart 메서드를 호출할 때 새 스레드가 호출하는 메서드를 래핑합니다. 한 번 이상 Start을(를) 호출하면 ThreadStateException가 던져진다.

메서드는 새 스레드가 실제로 시작되기 전에도 자주 즉시 반환됩니다. 및 ThreadState 속성을 사용하여 IsAlive 한 번에 스레드의 상태를 확인할 수 있지만 이러한 속성은 스레드 활동을 동기화하는 데 사용하면 안 됩니다.

비고

스레드가 시작되면 개체에 대한 참조 Thread 를 유지할 필요가 없습니다. 스레드 프로시저가 끝날 때까지 스레드가 계속 실행됩니다.

다음 코드 예제에서는 다른 개체에서 인스턴스 및 정적 메서드를 호출하는 두 개의 새 스레드를 만듭니다.

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 void Main()
    {
        ServerClass serverObject = new ServerClass();

        // Create the thread object, passing in the
        // serverObject.InstanceMethod method using a
        // ThreadStart delegate.
        Thread InstanceCaller = new(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
        // ServerClass.StaticMethod method using a
        // ThreadStart delegate.
        Thread StaticCaller = new(new ThreadStart(ServerClass.StaticMethod));

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

        Console.WriteLine("The Main() thread calls this after "
            + "starting the new StaticCaller thread.");
    }
}
// The example displays the output like the following:
//    The Main() thread calls this after starting the new InstanceCaller thread.
//    The Main() thread calls this after starting the new StaticCaller thread.
//    ServerClass.StaticMethod is running on another thread.
//    ServerClass.InstanceMethod is running on another thread.
//    The instance method called by the worker thread has ended.
//    The static method called by the worker thread has ended.
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

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

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

Public class Simple
    Public Shared Sub Main()
        Dim serverObject As New ServerClass()

        ' Create the thread object, passing in the
        ' serverObject.InstanceMethod method using a
        ' ThreadStart delegate.
        Dim InstanceCaller As New Thread(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.SharedMethod method using a
        ' ThreadStart delegate.
        Dim SharedCaller As New Thread( _
            New ThreadStart(AddressOf ServerClass.SharedMethod))

        ' Start the thread.
        SharedCaller.Start()

        Console.WriteLine("The Main() thread calls this after " _
            + "starting the new SharedCaller thread.")
    End Sub
End Class
' The example displays output like the following:
'    The Main() thread calls this after starting the new InstanceCaller thread.
'    The Main() thread calls this after starting the new StaticCaller thread.
'    ServerClass.StaticMethod is running on another thread.
'    ServerClass.InstanceMethod is running on another thread.
'    The instance method called by the worker thread has ended.
'    The static method called by the worker thread has ended.

스레드에 데이터 전달

대리자는 ParameterizedThreadStart을 호출할 때 데이터가 포함된 개체를 스레드에 쉽게 전달할 수 있는 방법을 제공합니다. 코드 예제를 ParameterizedThreadStart 참조하세요.

ParameterizedThreadStart 대리자를 사용하는 것은 Thread.Start(Object) 메서드가 모든 개체를 허용하기 때문에 형식 안전한 데이터 전달 방법이 아닙니다. 대안은 도우미 클래스의 스레드 프로시저 및 데이터를 캡슐화하고 대리자를 사용하여 ThreadStart 스레드 프로시저를 실행하는 것입니다. 다음 예제에서는 이 기술을 보여 줍니다.

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 _numberValue;

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

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

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

        // Create a thread to execute the task, and then
        // start the thread.
        Thread t = new(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 example displays the following output:
//       Main thread does some work, then waits.
//       This report displays the number 42.
//       Independent task has completed; main thread ends.
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 numberValue As Integer

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

    ' The thread procedure performs the task, such as formatting
    ' and printing a document.
    Public Sub ThreadProc()
        Console.WriteLine(boilerplate, numberValue)
    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(New ThreadStart(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
' The example displays the following output:
'       Main thread does some work, then waits.
'       This report displays the number 42.
'       Independent task has completed; main thread ends.

비동기 호출에서 데이터를 반환할 위치가 없기 때문에 둘 다 ThreadStartParameterizedThreadStart 반환 값도 없습니다. 스레드 메서드의 결과를 검색하려면 다음 섹션과 같이 콜백 메서드를 사용할 수 있습니다.

콜백 메서드를 사용하여 스레드에서 데이터 검색

다음 예제에서는 스레드에서 데이터를 검색하는 콜백 메서드를 보여 줍니다. 데이터를 포함하는 클래스의 생성자 및 스레드 메서드는 콜백 메서드를 나타내는 대리자도 허용합니다. 스레드 메서드가 종료되기 전에 콜백 대리자를 호출합니다.

using System;
using System.Threading;

// The ThreadWithState2 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 ThreadWithState2
{
    // State information used in the task.
    private string _boilerplate;
    private int _numberValue;

    // 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 ThreadWithState2(string text, int number,
        ExampleCallback callbackDelegate)
    {
        _boilerplate = text;
        _numberValue = 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, _numberValue);
        _callback?.Invoke(1);
    }
}

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

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

        Thread t = new(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 {lineCount} lines.");
    }
}

// The example displays the following output:
//       Main thread does some work, then waits.
//       This report displays the number 42.
//       Independent task printed 1 lines.
//       Independent task has completed; main thread ends.
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 numberValue 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(text As String, number As Integer, _
        callbackDelegate As ExampleCallback)
        boilerplate = text
        numberValue = 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, numberValue)
        If Not (callback Is Nothing) Then
            callback(1)
        End If
    End Sub
End Class

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

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, _
            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

    Public Shared Sub ResultCallback(lineCount As Integer)
        Console.WriteLine( _
            "Independent task printed {0} lines.", lineCount)
    End Sub
End Class
' The example displays the following output:
'       Main thread does some work, then waits.
'       This report displays the number 42.
'       Independent task printed 1 lines.
'       Independent task has completed; main thread ends.

참고하십시오