Thread.Join 方法

定義

封鎖呼叫執行緒,直到此執行個體所代表的執行緒終止為止。

多載

Join()

封鎖呼叫執行緒,直到此執行個體所代表的執行緒終止為止,但仍會繼續執行標準的 COM 與 SendMessage 提取作業。

Join(Int32)

封鎖呼叫執行緒,直到此執行個體代表的執行緒終止或超過指定的時間為止,但仍繼續執行標準的 COM 與 SendMessage 提取作業。

Join(TimeSpan)

封鎖呼叫執行緒,直到此執行個體代表的執行緒終止或超過指定的時間為止,但仍繼續執行標準的 COM 與 SendMessage 提取作業。

Join()

Source:
Thread.cs
Source:
Thread.cs
Source:
Thread.cs

封鎖呼叫執行緒,直到此執行個體所代表的執行緒終止為止,但仍會繼續執行標準的 COM 與 SendMessage 提取作業。

public:
 void Join();
public void Join ();
member this.Join : unit -> unit
Public Sub Join ()

例外狀況

呼叫端嘗試聯結處於 Unstarted 狀態的執行緒。

執行緒在等待時中斷。

備註

Join 是一種同步處理方法,會封鎖呼叫執行緒 (,也就是呼叫 方法的執行緒) 直到呼叫方法的執行緒 Join 已完成為止。 使用此方法可確保執行緒已終止。 如果執行緒未終止,呼叫端將會無限期地封鎖。 在下列範例中 Thread1 ,執行緒會呼叫 Join()Thread2 方法,這會導致 Thread1 封鎖直到 Thread2 完成為止。

using System;
using System.Threading;

public class Example
{
   static Thread thread1, thread2;
   
   public static void Main()
   {
      thread1 = new Thread(ThreadProc);
      thread1.Name = "Thread1";
      thread1.Start();
      
      thread2 = new Thread(ThreadProc);
      thread2.Name = "Thread2";
      thread2.Start();   
   }

   private static void ThreadProc()
   {
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      if (Thread.CurrentThread.Name == "Thread1" && 
          thread2.ThreadState != ThreadState.Unstarted)
         thread2.Join();
      
      Thread.Sleep(4000);
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      Console.WriteLine("Thread1: {0}", thread1.ThreadState);
      Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
   }
}
// The example displays output like the following:
//       Current thread: Thread1
//       
//       Current thread: Thread2
//       
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//       
//       
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
open System.Threading

let mutable thread1, thread2 =
    Unchecked.defaultof<Thread>, Unchecked.defaultof<Thread>

let threadProc () =
    printfn $"\nCurrent thread: {Thread.CurrentThread.Name}"

    if
        Thread.CurrentThread.Name = "Thread1"
        && thread2.ThreadState <> ThreadState.Unstarted
    then
        thread2.Join()

    Thread.Sleep 4000
    printfn $"\nCurrent thread: {Thread.CurrentThread.Name}"
    printfn $"Thread1: {thread1.ThreadState}"
    printfn $"Thread2: {thread2.ThreadState}\n"

thread1 <- Thread threadProc
thread1.Name <- "Thread1"
thread1.Start()

thread2 <- Thread threadProc
thread2.Name <- "Thread2"
thread2.Start()

// The example displays output like the following:
//       Current thread: Thread1
//
//       Current thread: Thread2
//
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//
//
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
Imports System.Threading

Module Example
   Dim thread1, thread2 As Thread

   Public Sub Main()
      thread1 = new Thread(AddressOf ThreadProc)
      thread1.Name = "Thread1"
      thread1.Start()
      
      thread2 = New Thread(AddressOf ThreadProc)
      thread2.Name = "Thread2"
      thread2.Start()   
   End Sub

   Private Sub ThreadProc()
      Console.WriteLine()
      Console.WriteLine("Current thread: {0}", Thread.CurrentThread.Name)
      If (Thread.CurrentThread.Name = "Thread1" And 
          thread2.ThreadState <> ThreadState.Unstarted)
         thread2.Join()
      End If
      Thread.Sleep(4000)
      Console.WriteLine()
      Console.WriteLine("Current thread: {0}", Thread.CurrentThread.Name)
      Console.WriteLine("Thread1: {0}", thread1.ThreadState)
      Console.WriteLine("Thread2: {0}", thread2.ThreadState)
      Console.WriteLine()
   End Sub
End Module
' The example displays output like the following :
'       Current thread: Thread1
'       
'       Current thread: Thread2
'       
'       Current thread: Thread2
'       Thread1: WaitSleepJoin
'       Thread2: Running
'       
'       
'       Current thread: Thread1
'       Thread1: Running
'       Thread2: Stopped

如果呼叫 時 Join 執行緒已經終止,方法會立即傳回。

警告

您不應該呼叫 Join 物件的方法,這個方法 Thread 代表目前線程中的目前線程。 這會導致您的應用程式變得沒有回應,因為目前的執行緒會無限期地等候。

這個方法會將呼叫執行緒的狀態變更為包含 ThreadState.WaitSleepJoin 。 您無法在處於狀態的 ThreadState.Unstarted 執行緒上叫 Join 用 。

另請參閱

適用於

Join(Int32)

Source:
Thread.cs
Source:
Thread.cs
Source:
Thread.cs

封鎖呼叫執行緒,直到此執行個體代表的執行緒終止或超過指定的時間為止,但仍繼續執行標準的 COM 與 SendMessage 提取作業。

public:
 bool Join(int millisecondsTimeout);
public bool Join (int millisecondsTimeout);
member this.Join : int -> bool
Public Function Join (millisecondsTimeout As Integer) As Boolean

參數

millisecondsTimeout
Int32

等候執行緒終止的毫秒數。

傳回

如果執行緒已經終止,為 true;如果 false 參數指定的時間量已經過去,而執行緒還沒有終止,則為 millisecondsTimeout

例外狀況

millisecondsTimeout 的值為負數,且不等於 Infinite (以毫秒為單位)。

無法啟動此執行緒。

millisecondsTimeout 小於 -1 (Timeout.Infinite)。

執行緒在等待時中斷。

備註

Join(Int32) 是一種同步處理方法,會封鎖呼叫執行緒 (,也就是呼叫 方法的執行緒) ,直到呼叫方法的執行緒 Join 已完成或逾時間隔經過為止。 在下列範例中 Thread1 ,執行緒會呼叫 Join()Thread2 方法,這會在 Thread1 完成之前或經過 2 秒之前 Thread2 封鎖。

using System;
using System.Threading;

public class Example
{
   static Thread thread1, thread2;
   
   public static void Main()
   {
      thread1 = new Thread(ThreadProc);
      thread1.Name = "Thread1";
      thread1.Start();
      
      thread2 = new Thread(ThreadProc);
      thread2.Name = "Thread2";
      thread2.Start();   
   }

   private static void ThreadProc()
   {
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      if (Thread.CurrentThread.Name == "Thread1" && 
          thread2.ThreadState != ThreadState.Unstarted)
         if (thread2.Join(2000))
            Console.WriteLine("Thread2 has termminated.");
         else
            Console.WriteLine("The timeout has elapsed and Thread1 will resume.");   
      
      Thread.Sleep(4000);
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      Console.WriteLine("Thread1: {0}", thread1.ThreadState);
      Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
   }
}
// The example displays the following output:
//       Current thread: Thread1
//       
//       Current thread: Thread2
//       The timeout has elapsed and Thread1 will resume.
//       
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//       
//       
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
open System.Threading

let mutable thread1, thread2 =
    Unchecked.defaultof<Thread>, Unchecked.defaultof<Thread>

let threadProc () =
    printfn $"\nCurrent thread: {Thread.CurrentThread.Name}"

    if
        Thread.CurrentThread.Name = "Thread1"
        && thread2.ThreadState <> ThreadState.Unstarted
    then
        if thread2.Join 2000 then
            printfn "Thread2 has termminated."
        else
            printfn "The timeout has elapsed and Thread1 will resume."

    Thread.Sleep 4000
    printfn $"\nCurrent thread: {Thread.CurrentThread.Name}"
    printfn $"Thread1: {thread1.ThreadState}"
    printfn $"Thread2: {thread2.ThreadState}\n"

thread1 <- Thread threadProc
thread1.Name <- "Thread1"
thread1.Start()

thread2 <- Thread threadProc
thread2.Name <- "Thread2"
thread2.Start()

// The example displays the following output:
//       Current thread: Thread1
//
//       Current thread: Thread2
//       The timeout has elapsed and Thread1 will resume.
//
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//
//
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
Imports System.Threading

Module Example
   Dim thread1, thread2 As Thread

   Public Sub Main()
      thread1 = new Thread(AddressOf ThreadProc)
      thread1.Name = "Thread1"
      thread1.Start()
      
      thread2 = New Thread(AddressOf ThreadProc)
      thread2.Name = "Thread2"
      thread2.Start()   
   End Sub

   Private Sub ThreadProc()
      Console.WriteLine()
      Console.WriteLine("Current thread: {0}", Thread.CurrentThread.Name)
      If (Thread.CurrentThread.Name = "Thread1" And 
          thread2.ThreadState <> ThreadState.Unstarted)
         If thread2.Join(TimeSpan.FromSeconds(2))
            Console.WriteLine("Thread2 has termminated.")
         Else
            Console.WriteLine("The timeout has elapsed and Thread1 will resume.")
         End If      
      End If
      Thread.Sleep(4000)
      Console.WriteLine()
      Console.WriteLine("Current thread: {0}", Thread.CurrentThread.Name)
      Console.WriteLine("Thread1: {0}", thread1.ThreadState)
      Console.WriteLine("Thread2: {0}", thread2.ThreadState)
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'       Current thread: Thread1
'       
'       Current thread: Thread2
'       
'       Current thread: Thread2
'       Thread1: WaitSleepJoin
'       Thread2: Running
'       
'       
'       Current thread: Thread1
'       Thread1: Running
'       Thread2: Stopped

如果 Timeout.InfinitemillisecondsTimeout 參數指定 ,則這個方法的行為與方法多載相同 Join() ,但傳回值除外。

如果呼叫 時 Join 執行緒已經終止,方法會立即傳回。

這個方法會將呼叫執行緒的狀態變更為包含 ThreadState.WaitSleepJoin 。 您無法在處於狀態的 ThreadState.Unstarted 執行緒上叫 Join 用 。

另請參閱

適用於

Join(TimeSpan)

Source:
Thread.cs
Source:
Thread.cs
Source:
Thread.cs

封鎖呼叫執行緒,直到此執行個體代表的執行緒終止或超過指定的時間為止,但仍繼續執行標準的 COM 與 SendMessage 提取作業。

public:
 bool Join(TimeSpan timeout);
public bool Join (TimeSpan timeout);
member this.Join : TimeSpan -> bool
Public Function Join (timeout As TimeSpan) As Boolean

參數

timeout
TimeSpan

TimeSpan,設定為等候執行緒終止的時間量。

傳回

如果執行緒終止了,為 true;如果 false 參數指定的時間量已經過去,而執行緒還沒有終止,則為 timeout

例外狀況

的值 timeout 為負數,且不等於 Infinite 毫秒,或大於 Int32.MaxValue 毫秒。

呼叫端嘗試聯結處於 Unstarted 狀態的執行緒。

範例

下列程式碼範例示範如何搭配 Join 方法使用 TimeSpan 值。

using namespace System;
using namespace System::Threading;

static TimeSpan waitTime = TimeSpan(0,0,1);

ref class Test
{
public:
   static void Work()
   {
      Thread::Sleep( waitTime );
   }

};

int main()
{
   Thread^ newThread = gcnew Thread( gcnew ThreadStart( Test::Work ) );
   newThread->Start();
   if ( newThread->Join( waitTime + waitTime ) )
   {
      Console::WriteLine( "New thread terminated." );
   }
   else
   {
      Console::WriteLine( "Join timed out." );
   }
}
// The example displays the following output:
//        New thread terminated.
using System;
using System.Threading;

class Test
{
    static TimeSpan waitTime = new TimeSpan(0, 0, 1);

    public static void Main() 
    {
        Thread newThread = new Thread(Work);
        newThread.Start();

        if(newThread.Join(waitTime + waitTime)) {
            Console.WriteLine("New thread terminated.");
        }
        else {
            Console.WriteLine("Join timed out.");
        }
    }

    static void Work()
    {
        Thread.Sleep(waitTime);
    }
}
// The example displays the following output:
//        New thread terminated.
open System
open System.Threading

let waitTime = TimeSpan(0, 0, 1)

let work () =
    Thread.Sleep waitTime

let newThread = Thread work
newThread.Start()

if waitTime + waitTime |> newThread.Join then
    printfn "New thread terminated."
else
    printfn "Join timed out."

// The example displays the following output:
//        New thread terminated.
Imports System.Threading

Public Module Test
    Dim waitTime As New TimeSpan(0, 0, 1)

    Public Sub Main() 
        Dim newThread As New Thread(AddressOf Work)
        newThread.Start()

        If newThread.Join(waitTime + waitTime) Then
            Console.WriteLine("New thread terminated.")
        Else
            Console.WriteLine("Join timed out.")
        End If
    End Sub

    Private Sub Work()
        Thread.Sleep(waitTime)
    End Sub
End Module
' The example displays the following output:
'       New thread terminated.

備註

Join(TimeSpan) 是一種同步處理方法,會封鎖呼叫執行緒 (,也就是呼叫 方法的執行緒) ,直到呼叫方法的執行緒 Join 已完成或逾時間隔經過為止。 在下列範例中 Thread1 ,執行緒會呼叫 Join()Thread2 方法,這會在 Thread1 完成之前或經過 2 秒之前 Thread2 封鎖。

using System;
using System.Threading;

public class Example
{
   static Thread thread1, thread2;
   
   public static void Main()
   {
      thread1 = new Thread(ThreadProc);
      thread1.Name = "Thread1";
      thread1.Start();
      
      thread2 = new Thread(ThreadProc);
      thread2.Name = "Thread2";
      thread2.Start();   
   }

   private static void ThreadProc()
   {
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      if (Thread.CurrentThread.Name == "Thread1" && 
          thread2.ThreadState != ThreadState.Unstarted)
         if (thread2.Join(TimeSpan.FromSeconds(2)))
            Console.WriteLine("Thread2 has termminated.");
         else
            Console.WriteLine("The timeout has elapsed and Thread1 will resume.");   
      
      Thread.Sleep(4000);
      Console.WriteLine("\nCurrent thread: {0}", Thread.CurrentThread.Name);
      Console.WriteLine("Thread1: {0}", thread1.ThreadState);
      Console.WriteLine("Thread2: {0}\n", thread2.ThreadState);
   }
}
// The example displays the following output:
//       Current thread: Thread1
//       
//       Current thread: Thread2
//       The timeout has elapsed and Thread1 will resume.
//       
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//       
//       
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
open System
open System.Threading

let mutable thread1, thread2 =
    Unchecked.defaultof<Thread>, Unchecked.defaultof<Thread>

let threadProc () =
    printfn $"\nCurrent thread: {Thread.CurrentThread.Name}"

    if
        Thread.CurrentThread.Name = "Thread1"
        && thread2.ThreadState <> ThreadState.Unstarted
    then
        if TimeSpan.FromSeconds 2 |> thread2.Join then
            printfn "Thread2 has termminated."
        else
            printfn "The timeout has elapsed and Thread1 will resume."

    Thread.Sleep 4000
    printfn $"\nCurrent thread: {Thread.CurrentThread.Name}"
    printfn $"Thread1: {thread1.ThreadState}"
    printfn $"Thread2: {thread2.ThreadState}\n"

thread1 <- Thread threadProc
thread1.Name <- "Thread1"
thread1.Start()

thread2 <- Thread threadProc
thread2.Name <- "Thread2"
thread2.Start()

// The example displays the following output:
//       Current thread: Thread1
//
//       Current thread: Thread2
//       The timeout has elapsed and Thread1 will resume.
//
//       Current thread: Thread2
//       Thread1: WaitSleepJoin
//       Thread2: Running
//
//
//       Current thread: Thread1
//       Thread1: Running
//       Thread2: Stopped
Imports System.Threading

Module Example
   Dim thread1, thread2 As Thread

   Public Sub Main()
      thread1 = new Thread(AddressOf ThreadProc)
      thread1.Name = "Thread1"
      thread1.Start()
      
      thread2 = New Thread(AddressOf ThreadProc)
      thread2.Name = "Thread2"
      thread2.Start()   
   End Sub

   Private Sub ThreadProc()
      Console.WriteLine()
      Console.WriteLine("Current thread: {0}", Thread.CurrentThread.Name)
      If (Thread.CurrentThread.Name = "Thread1" And 
          thread2.ThreadState <> ThreadState.Unstarted)
         If thread2.Join(2000)
            Console.WriteLine("Thread2 has termminated.")
         Else
            Console.WriteLine("The timeout has elapsed and Thread1 will resume.")
         End If      
      End If
      Thread.Sleep(4000)
      Console.WriteLine()
      Console.WriteLine("Current thread: {0}", Thread.CurrentThread.Name)
      Console.WriteLine("Thread1: {0}", thread1.ThreadState)
      Console.WriteLine("Thread2: {0}", thread2.ThreadState)
      Console.WriteLine()
   End Sub
End Module
' The example displays the following output:
'       Current thread: Thread1
'       
'       Current thread: Thread2
'       
'       Current thread: Thread2
'       Thread1: WaitSleepJoin
'       Thread2: Running
'       
'       
'       Current thread: Thread1
'       Thread1: Running
'       Thread2: Stopped

如果 Timeout.Infinitetimeout 指定 ,則這個方法的行為與 Join() 方法多載相同,但傳回值除外。

如果呼叫 時 Join 執行緒已經終止,方法會立即傳回。

這個方法會將目前線程的狀態變更為包含 WaitSleepJoin 。 您無法在處於狀態的 ThreadState.Unstarted 執行緒上叫 Join 用 。

另請參閱

適用於