Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Este artigo fornece comentários complementares à documentação de referência para esta API.
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 gerenciados pelo common language runtime.
Iniciar um thread
Inicie um thread fornecendo um delegado que representa o método que o thread deve executar em seu construtor de classe. Em seguida, você chama o Start método 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ê passará um delegado ThreadStart 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 a thread tiver sido executada por pelo menos cinco segundos, o loop terminará e a thread encerrará a execução.using System; using System.Diagnostics; using System.Threading; public class Example2 { public static void Main() { var th = new Thread(ExecuteInForeground); th.Start(); Thread.Sleep(1000); Console.WriteLine($"Main thread ({Thread.CurrentThread.ManagedThreadId}) exiting..."); } 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 {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000.0:N2} seconds"); 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 não tiver u argumento, você passará um delegado ParameterizedThreadStart 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 fazer a conversão (em C#) ou converter (no Visual Basic) o parâmetro para o tipo apropriado.
O exemplo a seguir é idêntico ao anterior, exceto que chama o construtor Thread(ParameterizedThreadStart). 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 Example3 { public static void Main() { var th = new Thread(ExecuteInForeground); th.Start(4500); Thread.Sleep(1000); Console.WriteLine($"Main thread ({Thread.CurrentThread.ManagedThreadId}) exiting..."); } 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 {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000.0:N2} seconds"); 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 executar até que o procedimento do thread seja concluído.
Recuperar objetos de thread
Você pode usar a propriedade estática (Shared
no Visual Basic) CurrentThread para recuperar uma referência ao encadeamento que está atualmente em execução a partir do código que esse encadeamento está executando. O exemplo a seguir usa a CurrentThread propriedade para exibir informações sobre o thread principal do aplicativo, outro thread em primeiro plano, um thread em segundo plano e um thread de pool de threads.
using System;
using System.Threading;
public class Example1
{
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 #{th.ManagedThreadId}: ");
Console.WriteLine($" Background thread: {th.IsBackground}");
Console.WriteLine($" Thread pool thread: {th.IsThreadPoolThread}");
Console.WriteLine($" Priority: {th.Priority}");
Console.WriteLine($" Culture: {th.CurrentCulture.Name}");
Console.WriteLine($" UI culture: {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 em primeiro plano e em segundo plano
As instâncias da classe Thread representam os threads em primeiro plano ou os threads em segundo plano. 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 em primeiro plano tiverem sido interrompidos, o runtime interromperá todos os threads e segundo plano e encerrará.
Por padrão, os seguintes threads são executados em primeiro plano:
O thread principal do aplicativo.
Todos os threads criados chamando um Thread construtor de classe.
Os seguintes threads são executados em segundo plano por padrão:
Os threads do pool de threads que vêm de um pool de threads de trabalho mantidos pelo runtime. Você pode configurar o pool de threads e agendar o trabalho nos threads do pool de threads usando a classe ThreadPool.
Observação
As operações assíncronas baseadas em tarefa são executadas automaticamente nos threads do pool de threads. As operações assíncronas baseadas em tarefas usam as classes Task e Task<TResult> para implementar o padrão assíncrono baseado em tarefa.
Todas as threads que entram no ambiente de execução gerenciada a partir do código não gerenciado.
Você pode alterar um thread para ser executado em segundo plano definindo a propriedade IsBackground a qualquer momento. Os threads em segundo plano são úteis para qualquer operação que deva continuar enquanto um aplicativo estiver em execução, mas não deve impedir que o aplicativo seja encerrado, como o monitoramento de alterações do sistema de arquivos ou as conexões de soquete de entrada.
O exemplo a seguir ilustra a diferença entre threads de primeiro plano e threads de segundo plano. É como o primeiro exemplo na seção Iniciar um thread , exceto que ele define o thread a ser executado em segundo plano antes de iniciá-lo. Como a saída mostra, 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 ({Thread.CurrentThread.ManagedThreadId}) exiting...");
}
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 {Thread.CurrentThread.ManagedThreadId}: Elapsed {sw.ElapsedMilliseconds / 1000.0:N2} seconds");
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 threads
Cada thread tem uma cultura, representada pela propriedade CurrentCulture, e uma cultura de interface do usuário, representada pela propriedade CurrentUICulture. A cultura atual fornece suporte às operações sensíveis à cultura, como análise e formatação, comparação e classificação de cadeias de caracteres, e também controla o sistema de escrita e o calendário usados por um thread. A cultura de interface do usuário atual fornece a recuperação de recursos sensíveis à cultura em arquivos de recursos.
Importante
As propriedades CurrentCulture e CurrentUICulture não funcionam de forma confiável quando usadas com qualquer thread diferente do thread atual. No .NET Framework, a leitura dessas propriedades é confiável, embora a definição dessas propriedades para um thread diferente do thread atual não o seja. No .NET Core, um InvalidOperationException será gerado se um thread tentar ler ou gravar essas propriedades em um thread diferente. Recomendamos que você use as propriedades CultureInfo.CurrentCulture e CultureInfo.CurrentUICulture para recuperar e definir a cultura atual.
Quando um novo thread é instanciado, sua cultura e cultura de 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 pela cultura da interface do usuário do thread do qual o novo thread é criado. Isso significa, por exemplo, que se a cultura atual do sistema for inglês (Estados Unidos) e a cultura atual do thread principal do aplicativo for francês (França), a cultura de um novo thread criado quando se chama o construtor Thread(ParameterizedThreadStart) direto do thread principal será o inglês (Estados Unidos) e não o francês (França). Para obter mais informações, consulte a seção "Cultura e threads" no tópico da classe CultureInfo.
Importante
Isso não se aplica a threads que executam operações assíncronas para aplicativos direcionados 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 do qual a operação assíncrona foi iniciada. Para obter mais informações, consulte a seção "Cultura e operações assíncronas baseadas em tarefas" das observações da CultureInfo classe.
Você pode fazer qualquer um dos seguintes procedimentos para garantir que todos os threads em execução em um aplicativo compartilhem a mesma cultura e cultura de interface do usuário:
Você pode passar um CultureInfo objeto que representa essa cultura para o ParameterizedThreadStart delegado ou o ThreadPool.QueueUserWorkItem(WaitCallback, Object) método.
Para aplicativos em execução no .NET Framework 4.5 e versões posteriores, você pode definir a cultura e a cultura da interface do usuário que serão atribuídas a todos os threads criados em um domínio de aplicativo, configurando o valor das propriedades CultureInfo.DefaultThreadCurrentCulture e CultureInfo.DefaultThreadCurrentUICulture. Observe que essa é uma configuração de domínio por aplicativo.
Para obter mais informações e exemplos, consulte a seção "Cultura e threads" das observações da classe CultureInfo.
Controlar os threads e obter suas respectivas informações
Você pode recuperar vários valores de propriedade que fornecem as informações sobre um thread. 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 para gravar uma vez que você pode usar para identificar um thread. O valor predefinido é
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; para o tempo de vida do thread, seu código hash não colidirá com o valor de qualquer outro thread, independentemente do domínio do aplicativo do qual você obtém o valor.
Um identificador de thread. O valor da propriedade ManagedThreadId somente leitura é atribuído pelo runtime e identifica exclusivamente um thread dentro de seu respectivo processo.
Observação
Um ThreadId do sistema operacional não tem nenhuma relação fixa com um thread gerenciado, pois 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 mover um thread gerenciado entre threads diferentes do sistema operacional.
O estado atual do thread. Durante toda a sua existência, um thread está sempre em um ou mais dos estados definidos pela propriedade ThreadState.
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 respeitado pelo sistema operacional.
A propriedade IsThreadPoolThread somente leitura, que indica se um thread é um thread de pool de threads.
A propriedade de IsBackground . Para obter mais informações, consulte a seção Threads em primeiro plano e em segundo plano.
Exemplos
O exemplo a seguir demonstra a funcionalidade de threading simples.
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: {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
Esse 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.