Threading gerenciado e não gerenciado no Windows

O gerenciamento de todos os threads é feito através da Thread classe, incluindo threads criados pelo common language runtime e aqueles criados fora do tempo de execução que entram no ambiente gerenciado para executar código. O tempo de execução monitora todos os threads em seu processo que já executaram código dentro do ambiente de execução gerenciado. Ele não rastreia nenhum outro tópico. Os threads podem entrar no ambiente de execução gerenciado por meio da interoperabilidade COM (porque o tempo de execução expõe objetos gerenciados como objetos COM para o mundo não gerenciado), a função COM DllGetClassObject e a chamada de plataforma.

Quando um thread não gerenciado entra no tempo de execução através, por exemplo, de um wrapper chamável COM, o sistema verifica o armazenamento local de thread desse thread para procurar um objeto gerenciado Thread interno. Se um for encontrado, o tempo de execução já está ciente desse thread. No entanto, se não conseguir encontrar um, o tempo de execução cria um novo Thread objeto e o instala no armazenamento local de thread desse thread.

No threading gerenciado, Thread.GetHashCode é a identificação de thread gerenciado estável. Durante o tempo de vida do thread, ele não colidirá com o valor de nenhum outro thread, independentemente do domínio do aplicativo do qual você obtém esse valor.

Mapeamento de threading do Win32 para threading gerenciado

A tabela a seguir mapeia elementos de threading do Win32 para seu equivalente de tempo de execução aproximado. Observe que esse mapeamento não representa funcionalidade idêntica. Por exemplo, TerminateThread não executa cláusulas finais ou libera recursos e não pode ser impedido. No entanto, Thread.Abort executa todo o seu código de reversão, recupera todos os recursos e pode ser negado usando ResetAborto . Certifique-se de ler a documentação atentamente antes de fazer suposições sobre a funcionalidade.

No Win32 No common language runtime
CreateThread Combinação de rosca e ThreadStart
TerminateThread Thread.Abort
SuspendThread Thread.Suspend
ResumeThread Thread.Resume
Dormir Thread.Sleep
WaitForSingleObject na alça de thread Thread.Join
ExitThread Sem equivalente
GetCurrentThread Thread.CurrentThread
SetThreadPriority Thread.Priority
Sem equivalente Thread.Name
Sem equivalente Thread.IsBackground
Perto de CoInitializeEx (OLE32.DLL) Thread.ApartmentState

Tópicos gerenciados e apartamentos COM

Um thread gerenciado pode ser marcado para indicar que ele hospedará um apartamento single-threaded ou multithreaded . (Para obter mais informações sobre a arquitetura de threading COM, consulte Processos, tópicos e apartamentos.) O GetApartmentState, SetApartmentState, e TrySetApartmentState os métodos da classe retornam e atribuem Thread o estado de apartamento de um thread. Se o estado não tiver sido definido, GetApartmentState retorna ApartmentState.Unknown.

A propriedade pode ser definida apenas quando o thread está no ThreadState.Unstarted estado, pode ser definida apenas uma vez para um thread.

Se o estado do apartamento não estiver definido antes do thread ser iniciado, o thread será inicializado como um apartamento multithreaded (MTA). O thread do finalizador e todos os threads controlados por ThreadPool são MTA.

Importante

Para o código de inicialização do aplicativo, a única maneira de controlar o estado do apartamento é aplicar o MTAThreadAttribute ou o STAThreadAttribute procedimento ao ponto de entrada.

Os objetos gerenciados expostos a COM se comportam como se tivessem agregado o marshaller de thread livre. Em outras palavras, eles podem ser chamados de qualquer apartamento COM de forma livre. Os únicos objetos gerenciados que não exibem esse comportamento de thread livre são os objetos que derivam de ServicedComponent ou StandardOleMarshalObject.

No mundo gerenciado, não há suporte para o a menos que você use contextos e instâncias gerenciadas ligadas ao SynchronizationAttribute contexto. Se você estiver usando o Enterprise Services, seu objeto deverá derivar de (que é derivado de ServicedComponentContextBoundObject).

Quando o código gerenciado chama objetos COM, ele sempre segue as regras COM. Em outras palavras, ele chama através de proxies de apartamento COM e wrappers de contexto COM+ 1.0, conforme ditado pelo OLE32.

Problemas de bloqueio

Se um thread fizer uma chamada não gerenciada para o sistema operacional que bloqueou o thread em código não gerenciado, o tempo de execução não assumirá o controle dele para Thread.Interrupt ou Thread.Abort. No caso do , o tempo de Thread.Abortexecução marca o thread para Abort e assume o controle dele quando ele reinsere o código gerenciado. É preferível usar o bloqueio gerenciado em vez do bloqueio não gerenciado. WaitHandle.WaitOne,WaitHandle.WaitAny, WaitHandle.WaitAll, Monitor.Enter, , Monitor.TryEnter, GC.WaitForPendingFinalizersThread.Join, e assim por diante são todos responsivos a Thread.Interrupt e para Thread.Abort. Além disso, se o seu thread estiver em um apartamento de thread único, todas essas operações de bloqueio gerenciadas bombearão corretamente as mensagens em seu apartamento enquanto o thread estiver bloqueado.

Fios e fibras

O modelo de threading .NET não suporta fibras. Você não deve chamar qualquer função não gerenciada que é implementada usando fibras. Essas chamadas podem resultar em uma falha do tempo de execução do .NET.

Consulte também