Thread Classe

Definição

Cria e controla uma thread, define a sua prioridade e obtém o seu estado.

public ref class Thread sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject
public ref class Thread sealed
public ref class Thread sealed : System::Runtime::InteropServices::_Thread
public ref class Thread sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject, System::Runtime::InteropServices::_Thread
public sealed class Thread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class Thread
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
public sealed class Thread : System.Runtime.InteropServices._Thread
[System.Runtime.InteropServices.ComVisible(true)]
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
public sealed class Thread : System.Runtime.ConstrainedExecution.CriticalFinalizerObject, System.Runtime.InteropServices._Thread
type Thread = class
    inherit CriticalFinalizerObject
[<System.Runtime.InteropServices.ComVisible(true)>]
type Thread = class
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
type Thread = class
    interface _Thread
[<System.Runtime.InteropServices.ComVisible(true)>]
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
type Thread = class
    inherit CriticalFinalizerObject
    interface _Thread
Public NotInheritable Class Thread
Inherits CriticalFinalizerObject
Public NotInheritable Class Thread
Public NotInheritable Class Thread
Implements _Thread
Public NotInheritable Class Thread
Inherits CriticalFinalizerObject
Implements _Thread
Herança
Herança
Thread
Atributos
Implementações

Exemplos

O exemplo a seguir demonstra uma funcionalidade simples de encadeamento.

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: {0}", 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

Este código produz uma saída semelhante à seguinte:

[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.

Observações

A Thread classe cria e controla um thread, define sua prioridade e obtém seu status.

Quando um processo é iniciado, o common language runtime cria automaticamente um único thread de primeiro plano para executar o código do aplicativo. Junto com esse thread de primeiro plano principal, um processo pode criar um ou mais threads para executar uma parte do código do programa associado ao processo. Esses threads podem ser executados em primeiro plano ou em segundo plano. Além disso, você pode usar a ThreadPool classe para executar código em threads de trabalho que são gerenciados pelo common language runtime.

Iniciar um thread

Você inicia um thread fornecendo um delegado que representa o método que o thread deve executar em seu construtor de classe. Em seguida, chame o método Start para iniciar a execução.

Os Thread construtores podem usar qualquer um dos dois tipos de delegado, dependendo se você pode passar um argumento para o método a ser executado:

  • Se o método não tiver argumentos, você passa um ThreadStart delegado para o construtor. Tem a assinatura:

    public delegate void ThreadStart()
    
    Public Delegate Sub ThreadStart()
    

    O exemplo a seguir cria e inicia um thread que executa o ExecuteInForeground método. O método exibe informações sobre algumas propriedades de thread e, em seguida, executa um loop no qual ele pausa por meio segundo e exibe o número decorrido de segundos. Quando o thread é executado por pelo menos cinco segundos, o loop termina e o thread encerra a execução.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    public class Example
    {
       public static void Main()
       {
          var th = new Thread(ExecuteInForeground);
          th.Start();
          Thread.Sleep(1000);
          Console.WriteLine("Main thread ({0}) exiting...",
                            Thread.CurrentThread.ManagedThreadId);
       }
    
       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 {0}: Elapsed {1:N2} seconds",
                               Thread.CurrentThread.ManagedThreadId,
                               sw.ElapsedMilliseconds / 1000.0);
             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
    
  • Se o método tiver um argumento, você passa um ParameterizedThreadStart delegado para o construtor. Tem a assinatura:

    public delegate void ParameterizedThreadStart(object obj)
    
    Public Delegate Sub ParameterizedThreadStart(obj As Object)
    

    O método executado pelo delegado pode então converter (em C#) ou converter (em Visual Basic) o parâmetro para o tipo apropriado.

    O exemplo a seguir é idêntico ao anterior, exceto que ele chama o Thread(ParameterizedThreadStart) construtor. Esta versão do ExecuteInForeground método tem um único parâmetro que representa o número aproximado de milissegundos que o loop deve executar.

    using System;
    using System.Diagnostics;
    using System.Threading;
    
    public class Example
    {
       public static void Main()
       {
          var th = new Thread(ExecuteInForeground);
          th.Start(4500);
          Thread.Sleep(1000);
          Console.WriteLine("Main thread ({0}) exiting...",
                            Thread.CurrentThread.ManagedThreadId);
       }
    
       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 {0}: Elapsed {1:N2} seconds",
                               Thread.CurrentThread.ManagedThreadId,
                               sw.ElapsedMilliseconds / 1000.0);
             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
    

Não é necessário manter uma referência a um Thread objeto depois de iniciar o thread. O thread continua a ser executado até que o procedimento do thread seja concluído.

Recuperar objetos Thread

Você pode usar a propriedade static (Shared no Visual Basic) CurrentThread para recuperar uma referência ao thread em execução no momento do código que o thread está executando. O exemplo a seguir usa a CurrentThread propriedade para exibir informações sobre o thread principal do aplicativo, outro thread de primeiro plano, um thread de plano de fundo e um thread de pool de threads.

using System;
using System.Threading;

public class Example
{
   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 #{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();
      }   
   }
}
// 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

Threads de primeiro e segundo plano

As instâncias da classe representam threads de primeiro plano ou threads de Thread plano de fundo. Os threads em segundo plano são idênticos aos threads de primeiro plano, com uma exceção: um thread em segundo plano não mantém um processo em execução se todos os threads de primeiro plano tiverem terminado. Depois que todos os threads de primeiro plano forem interrompidos, o tempo de execução interromperá todos os threads em segundo plano e será desligado.

Por padrão, os seguintes threads são executados em primeiro plano:

  • O thread principal do aplicativo.

  • Todos os threads criados chamando um construtor de Thread classe.

Os seguintes threads são executados em segundo plano por padrão:

  • Threads do thread pool, que vêm de um pool de threads de trabalho mantido pelo runtime. Você pode configurar o pool de threads e agendar o trabalho em threads do pool usando a classe ThreadPool.

    Note

    As operações assíncronas baseadas em tarefas são performadas automaticamente em threads do pool de threads. As operações assíncronas baseadas em tarefas usam as Task classes e Task<TResult> para implementar o padrão assíncrono baseado em tarefas.

  • Todos os threads que entram no ambiente de execução gerenciado a partir de código não gerenciado.

Você pode alterar um thread para executar em segundo plano definindo a IsBackground propriedade a qualquer momento. Os threads em segundo plano são úteis para qualquer operação que deve continuar enquanto um aplicativo estiver em execução, mas não deve impedir que o aplicativo seja encerrado, como o monitoramento de alterações no sistema de arquivos ou conexões de soquete de entrada.

O exemplo a seguir ilustra a diferença entre threads de primeiro plano e de plano de fundo. É como o primeiro exemplo na seção Iniciar um thread , exceto que ele define o thread para ser executado em segundo plano antes de iniciá-lo. Como mostra a saída, o loop é interrompido antes de ser executado por cinco segundos.

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 ({0}) exiting...",
                        Thread.CurrentThread.ManagedThreadId);
   }

   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 {0}: Elapsed {1:N2} seconds",
                           Thread.CurrentThread.ManagedThreadId,
                           sw.ElapsedMilliseconds / 1000.0);
         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...

Cultura e tópicos

Cada thread tem uma cultura, representada pela CurrentCulture propriedade, e uma cultura da interface do usuário, representada pela CurrentUICulture propriedade. A cultura atual oferece suporte a operações sensíveis à cultura, como análise e formatação, comparação de cadeia de caracteres e classificação, e também controla o sistema de escrita e o calendário usados por um thread. A cultura atual da interface do usuário fornece recuperação sensível à cultura de recursos em arquivos de recursos.

Importante

As CurrentCulture propriedades e CurrentUICulture não funcionam de forma confiável quando usadas com qualquer thread diferente do thread atual. Um InvalidOperationException é lançado se um thread tentar ler ou escrever estas propriedades noutro thread. Recomendamos que use as propriedades CultureInfo.CurrentCulture e CultureInfo.CurrentUICulture para recuperar e definir a cultura atual.

Quando um novo thread é instanciado, sua cultura e cultura da interface do usuário são definidas pela cultura atual do sistema e pela cultura da interface do usuário, e não pela cultura e cultura da interface do usuário do thread a partir do qual o novo thread é criado. Isso significa, por exemplo, que se a cultura do sistema atual for inglês (Estados Unidos) e a cultura atual do thread do aplicativo primário for francesa (França), a cultura de um novo thread criado chamando o Thread(ParameterizedThreadStart) construtor do thread primário será inglês (Estados Unidos) e não francês (França). Para obter mais informações, consulte a seção "Cultura e tópicos" do tópico da CultureInfo classe.

Importante

Isso não é verdade para threads que executam operações assíncronas para aplicativos destinados ao .NET Framework 4.6 e versões posteriores. Nesse caso, a cultura e a cultura da interface do usuário fazem parte do contexto de uma operação assíncrona; o thread no qual uma operação assíncrona é executada por padrão herda a cultura e a cultura da interface do usuário do thread a partir do qual a operação assíncrona foi iniciada. Para obter mais informações, consulte a secção "Cultura e operações assíncronas baseadas em tarefas" nos comentários da classe CultureInfo.

Você pode fazer o seguinte para garantir que todos os threads executados em um aplicativo compartilhem a mesma cultura e cultura da interface do usuário:

Para obter mais informações e exemplos, consulte a seção "Cultura e tópicos" das CultureInfo observações da classe.

Obter informações e controlar fluxos de execução

Pode-se recuperar vários valores de propriedade que fornecem informações sobre um tópico. Em alguns casos, você também pode definir esses valores de propriedade para controlar a operação do thread. Essas propriedades de thread incluem:

  • Um nome. Name é uma propriedade write-once que você pode usar para identificar um thread. O seu valor padrão é null.

  • Um código hash, que você pode recuperar chamando o GetHashCode método. O código hash pode ser usado para identificar exclusivamente um thread; Durante o tempo de vida do thread, seu código hash não colidirá com o valor de nenhum outro thread, independentemente do domínio do aplicativo do qual você obtém o valor.

  • Um ID de thread. O valor da propriedade ManagedThreadId de leitura apenas é atribuído durante o tempo de execução e identifica exclusivamente o thread dentro do seu processo.

    Note

    Um ThreadId do sistema operacional não tem nenhuma relação fixa com um thread gerenciado, porque um host não gerenciado pode controlar a relação entre threads gerenciados e não gerenciados. Especificamente, um host sofisticado pode usar a API de hospedagem CLR para agendar muitos threads gerenciados no mesmo thread do sistema operacional ou para mover um thread gerenciado entre diferentes threads do sistema operacional.

  • O estado atual do thread. Durante a sua existência, um fio está sempre em um ou mais dos estados definidos pela ThreadState propriedade.

  • Um nível de prioridade de agendamento, que é definido pela ThreadPriority propriedade. Embora você possa definir esse valor para solicitar a prioridade de um thread, não é garantido que ele seja honrado pelo sistema operacional.

  • A propriedade de leitura única IsThreadPoolThread, que indica se uma thread faz parte do pool de threads.

  • A propriedade IsBackground. Para obter mais informações, consulte a secção Tópicos em primeiro plano e em segundo plano.

Construtores

Name Descrição
Thread(ParameterizedThreadStart, Int32)

Inicializa uma nova instância da Thread classe, especificando um delegado que permite que um objeto seja passado para a thread quando a thread é iniciada e especificando o tamanho máximo da pilha da thread.

Thread(ParameterizedThreadStart)

Inicializa uma nova instância da Thread classe, especificando um delegado que permite que um objeto seja passado para a thread quando a thread é iniciada.

Thread(ThreadStart, Int32)

Inicializa uma nova instância da Thread classe, especificando o tamanho máximo da pilha para a thread.

Thread(ThreadStart)

Inicializa uma nova instância da Thread classe.

Propriedades

Name Descrição
ApartmentState
Obsoleto.
Obsoleto.

Percebe ou define o estado do apartamento deste tópico.

CurrentContext

Obtém o contexto atual em que a thread está a ser executada.

CurrentCulture

Obtém ou define a cultura do tópico atual.

CurrentPrincipal

Obtém ou define o principal atual do thread (para segurança baseada em funções).

CurrentThread

Fica com o tópico que está a correr atualmente.

CurrentUICulture

Obtém ou define a cultura atual usada pelo Resource Manager para consultar recursos específicos da cultura em tempo de execução.

ExecutionContext

Obtém um ExecutionContext objeto que contém informação sobre os vários contextos da thread atual.

IsAlive

Recebe um valor que indica o estado de execução da thread atual.

IsBackground

Recebe ou define um valor que indica se um thread é ou não um thread em segundo plano.

IsThreadPoolThread

Recebe um valor que indica se uma thread pertence ou não ao pool de threads geridos.

ManagedThreadId

Obtém um identificador único para a thread gerida atual.

Name

Obtém ou define o nome do tópico.

Priority

Recebe ou define um valor que indica a prioridade de agendamento de uma thread.

ThreadState

Obtém um valor contendo os estados do thread atual.

Métodos

Name Descrição
Abort()
Obsoleto.

Eleva a ThreadAbortException no thread onde é invocado, para iniciar o processo de terminação do thread. Chamar este método normalmente termina o thread.

Abort(Object)
Obsoleto.

Levanta a ThreadAbortException no thread onde é invocado, para iniciar o processo de terminação do thread, fornecendo também informação de exceção sobre a terminação do thread. Chamar este método normalmente termina o thread.

AllocateDataSlot()

Aloca um slot de dados sem nome em todos os threads. Para melhor desempenho, use campos marcados com o ThreadStaticAttribute atributo em vez disso.

AllocateNamedDataSlot(String)

Aloca um slot de dados nomeado em todos os threads. Para melhor desempenho, use campos marcados com o ThreadStaticAttribute atributo em vez disso.

BeginCriticalRegion()

Notifica um host que a execução está prestes a entrar numa região de código em que os efeitos de um aborto de thread ou exceção não tratada podem pôr em risco outras tarefas no domínio da aplicação.

BeginThreadAffinity()

Notifica um host que o código gerido está prestes a executar instruções que dependem da identidade do thread físico atual do sistema operativo.

DisableComObjectEagerCleanup()

Desliga a limpeza automática dos wrappers chamáveis em tempo de execução (RCW) para a thread atual.

EndCriticalRegion()

Notifica um host que a execução está prestes a entrar numa região de código em que os efeitos de um aborto de thread ou exceção não tratada são limitados à tarefa atual.

EndThreadAffinity()

Notifica um host que o código gerido terminou de executar instruções que dependem da identidade do thread atual do sistema operativo físico.

Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.

(Herdado de Object)
Finalize()

Assegura que os recursos são libertados e que outras operações de limpeza são realizadas quando o coletor de lixo recupera o Thread objeto.

FreeNamedDataSlot(String)

Elimina a associação entre um nome e um espaço, para todas as threads no processo. Para melhor desempenho, use campos marcados com o ThreadStaticAttribute atributo em vez disso.

GetApartmentState()

Devolve um ApartmentState valor que indica o estado do apartamento.

GetCompressedStack()
Obsoleto.
Obsoleto.

Devolve um CompressedStack objeto que pode ser usado para capturar a pilha do thread atual.

GetCurrentProcessorId()

Recebe um ID usado para indicar em que processador o thread atual está a executar.

GetData(LocalDataStoreSlot)

Recupera o valor do slot especificado na thread atual, dentro do domínio atual da thread atual. Para melhor desempenho, use campos marcados com o ThreadStaticAttribute atributo em vez disso.

GetDomain()

Devolve o domínio atual onde o thread atual está a correr.

GetDomainID()

Devolve um identificador único do domínio da aplicação.

GetHashCode()

Devolve um código hash para o thread atual.

GetHashCode()

Serve como função de hash predefinida.

(Herdado de Object)
GetNamedDataSlot(String)

Procura um slot de dados nomeado. Para melhor desempenho, use campos marcados com o ThreadStaticAttribute atributo em vez disso.

GetType()

Obtém o Type da instância atual.

(Herdado de Object)
Interrupt()

Interrompe um thread que está no WaitSleepJoin estado do thread.

Join()

Bloqueia o thread que chama até que o thread representado por esta instância termine, continuando a realizar o COM e SendMessage bombeamento padrão.

Join(Int32)

Bloqueia o thread que chama até que o thread representado por esta instância termine ou o tempo especificado decorra, continuando a realizar o COM padrão e o encaminhamento de mensagens.

Join(TimeSpan)

Bloqueia o thread que chama até que o thread representado por esta instância termine ou o tempo especificado decorra, continuando a realizar o COM padrão e o encaminhamento de mensagens.

MemberwiseClone()

Cria uma cópia superficial do atual Object.

(Herdado de Object)
MemoryBarrier()

Sincroniza o acesso à memória da seguinte forma: O processador que executa o thread atual não pode reordenar instruções de forma a que os acessos à memória antes da chamada sejam MemoryBarrier() executados após os acessos à memória que seguem a chamada para MemoryBarrier().

ResetAbort()
Obsoleto.

Cancela um Abort(Object) pedido para o tópico atual.

Resume()
Obsoleto.
Obsoleto.
Obsoleto.

Retoma um tópico que foi suspenso.

SetApartmentState(ApartmentState)

Define o estado do apartamento de um tópico antes de ser iniciado.

SetCompressedStack(CompressedStack)
Obsoleto.
Obsoleto.

Aplica um capturado CompressedStack ao tópico atual.

SetData(LocalDataStoreSlot, Object)

Define os dados no slot especificado na thread em curso, para o domínio atual dessa thread. Para melhor desempenho, use campos marcados com o ThreadStaticAttribute atributo em vez disso.

Sleep(Int32)

Suspende o fio atual durante o número especificado de milissegundos.

Sleep(TimeSpan)

Suspende o thread atual durante o tempo especificado.

SpinWait(Int32)

Faz com que um thread espere o número de vezes definido pelo iterations parâmetro.

Start()

Faz com que o sistema operativo altere o estado da instância atual para Running.

Start(Object)

Faz com que o sistema operativo altere o estado da instância atual para Running, e opcionalmente fornece um objeto contendo dados a serem usados pelo método que a thread executa.

Suspend()
Obsoleto.
Obsoleto.
Obsoleto.

Ou suspende a linha, ou se a linha já estiver suspensa, não tem efeito.

ToString()

Devolve uma cadeia que representa o objeto atual.

(Herdado de Object)
TrySetApartmentState(ApartmentState)

Define o estado do apartamento de um tópico antes de ser iniciado.

UnsafeStart()

Faz com que o sistema operativo altere o estado da instância atual para Running.

UnsafeStart(Object)

Faz com que o sistema operativo altere o estado da instância atual para Running, e opcionalmente fornece um objeto contendo dados a serem usados pelo método que a thread executa.

VolatileRead(Byte)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(Double)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(Int16)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(Int32)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(Int64)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(IntPtr)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(Object)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(SByte)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(Single)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(UInt16)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(UInt32)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(UInt64)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileRead(UIntPtr)
Obsoleto.

Lê o valor de um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer após este método no código, o processador não pode movê-lo antes deste método.

VolatileWrite(Byte, Byte)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(Double, Double)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(Int16, Int16)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(Int32, Int32)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(Int64, Int64)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(IntPtr, IntPtr)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(Object, Object)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(SByte, SByte)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(Single, Single)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(UInt16, UInt16)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(UInt32, UInt32)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(UInt64, UInt64)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

VolatileWrite(UIntPtr, UIntPtr)
Obsoleto.

Escreve um valor para um campo. Em sistemas que o requerem, insere uma barreira de memória que impede o processador de reordenar as operações de memória da seguinte forma: Se uma leitura ou escrita aparecer antes deste método no código, o processador não pode movê-lo após esse método.

Yield()

Faz com que a thread que chama dê a execução a outra thread pronta para correr no processador atual. O sistema operativo seleciona o thread a ceder.

Implementações de Interface Explícita

Name Descrição
_Thread.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr)

Mapeia um conjunto de nomes para um conjunto correspondente de identificadores de despacho.

_Thread.GetTypeInfo(UInt32, UInt32, IntPtr)

Recupera as informações de tipo de um objeto, que podem ser usadas para obter as informações de tipo para uma interface.

_Thread.GetTypeInfoCount(UInt32)

Recupera o número de interfaces de informações de tipo que um objeto fornece (0 ou 1).

_Thread.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr)

Proporciona acesso a propriedades e métodos expostos por um objeto.

Aplica-se a

Segurança de Thread

Este tipo é seguro para fios.

Ver também