Lock Classe
Definição
Importante
Algumas informações dizem respeito a um produto pré-lançado que pode ser substancialmente modificado antes de ser lançado. A Microsoft não faz garantias, de forma expressa ou implícita, em relação à informação aqui apresentada.
Fornece um mecanismo para alcançar exclusão mútua em regiões de código entre diferentes threads.
public ref class Lock sealed
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
- Herança
-
Lock
Observações
A Lock classe pode ser usada para definir regiões de código que exigem acesso mutuamente exclusivo entre threads de um processo, comumente chamadas de secções críticas, para evitar acessos concorrentes a um recurso. A Lock pode ser introduzido e sair, onde a região de código entre o enter e o exit é uma secção crítica associada ao bloqueio. Diz-se que uma fiação que entra numa fechadura segura ou possui a fechadura até sair da fechadura. No máximo, um fio pode segurar um cadeado a qualquer momento. Uma rosca pode conter várias fechaduras. Um thread pode entrar numa fechadura várias vezes antes de sair dela, como recursivamente. Um thread que não pode entrar imediatamente num bloqueio pode esperar até que o bloqueio possa ser aberto ou até que um timeout especificado expire.
Ao usar os Enter métodos ou TryEnter para abrir uma fechadura:
- Certifique-se de que a thread sai do bloqueio de Exit forma uniforme em caso de exceções, como em C#, usando um
try/finallybloco. - Quando a fechadura está a ser introduzida e saída num método C#
async, certifique-se de que nãoawaithá espaço entre a entrada e a saída. Os bloqueios são mantidos por threads e o código que se segueawaitpode correr numa thread diferente.
Recomenda-se usar o EnterScope método com uma construção de linguagem que elimine automaticamente o retorno Lock.Scope , como a palavra-chave C# using , ou usar a palavra-chave C# lock , pois estes garantem que o bloqueio é encerrado em casos excecionais. Estes padrões também podem ter benefícios de desempenho em relação ao uso Enter/TryEnter de e Exit. O seguinte fragmento de código ilustra vários padrões para entrar e sair de uma fechadura.
public sealed class ExampleDataStructure
{
private readonly Lock _lockObj = new();
public void Modify()
{
lock (_lockObj)
{
// Critical section associated with _lockObj
}
using (_lockObj.EnterScope())
{
// Critical section associated with _lockObj
}
_lockObj.Enter();
try
{
// Critical section associated with _lockObj
}
finally { _lockObj.Exit(); }
if (_lockObj.TryEnter())
{
try
{
// Critical section associated with _lockObj
}
finally { _lockObj.Exit(); }
}
}
}
Ao usar a palavra-chave C# lock ou semelhante para entrar e sair de um bloqueio, o tipo da expressão deve ser precisamente System.Threading.Lock. Se o tipo da expressão for qualquer outro, como Object ou um tipo genérico como T, pode ser usada uma implementação diferente que não seja intercambiável (como Monitor). Para mais informações, consulte a especificação relevante do compilador.
Interrupt pode interromper threads que estão à espera de entrar num bloqueio. Em threads STA do Windows, as esperas por bloqueios permitem o pump de mensagens que pode executar outro código no mesmo thread durante uma espera. Algumas funcionalidades das esperas podem ser substituídas por um personalizado SynchronizationContext.
Note
Uma thread que entra num bloqueio, incluindo várias vezes como recursivamente, deve sair do bloqueio o mesmo número de vezes para sair totalmente do bloqueio e permitir que outros threads entrem no bloqueio. Se um fio sair enquanto segura um Lock, o comportamento do Lock torna-se indefinido.
Atenção
Se, num caminho de código, um thread puder entrar em múltiplos bloqueios antes de sair deles, certifique-se de que todos os caminhos de código que possam entrar em quaisquer dois desses bloqueios no mesmo thread os inserem na mesma ordem. Caso contrário, pode levar a impasses. Por exemplo, considere que num caminho T1 de código thread entra em lock L1 e depois lock L2 antes de sair de ambos, e noutro code path thread T2 entra em ambos os locks na ordem inversa. Nesse cenário, seria possível que a seguinte ordem de eventos ocorresse: T1 entraL1, L2T2 entra, T1 tenta entrar L2 e espera, T2 tenta entrar L1 e espera. Há um impasse entre T1 e T2 isso não pode ser resolvido, e quaisquer outros threads que tentem entrar em qualquer um dos bloqueios no futuro também ficam bloqueados.
Construtores
| Name | Description |
|---|---|
| Lock() |
Inicializa uma nova instância da Lock classe. |
Propriedades
| Name | Description |
|---|---|
| IsHeldByCurrentThread |
Obtém um valor que indica se o bloqueio é mantido pelo thread atual. |
Métodos
| Name | Description |
|---|---|
| Enter() |
Entra na fechadura, esperando se necessário até que a fechadura possa ser aberta. |
| EnterScope() |
Entra na fechadura, esperando se necessário até que a fechadura possa ser aberta. |
| Equals(Object) |
Determina se o objeto especificado é igual ao objeto atual. (Herdado de Object) |
| Exit() |
Sai da fechadura. |
| GetHashCode() |
Serve como função de hash predefinida. (Herdado de Object) |
| GetType() |
Obtém o Type da instância atual. (Herdado de Object) |
| MemberwiseClone() |
Cria uma cópia superficial do atual Object. (Herdado de Object) |
| ToString() |
Devolve uma cadeia que representa o objeto atual. (Herdado de Object) |
| TryEnter() |
Tenta entrar na eclusa sem esperar. |
| TryEnter(Int32) |
Tenta entrar na fechadura, esperando se necessário o número especificado de milissegundos até que a fechadura possa ser aberta. |
| TryEnter(TimeSpan) |
Tenta entrar na fechadura, esperando se necessário até que a fechadura possa ser aberta ou até que o tempo especificado expire. |