Lock Classe

Definição

Fornece um mecanismo para alcançar a exclusão mútua em regiões de código entre threads diferentes.

public ref class Lock sealed
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
Herança
Lock

Comentários

A Lock classe pode ser usada para definir regiões de código que exigem acesso mutuamente exclusivo entre threads de um processo, normalmente chamado de seções críticas, para impedir acessos simultâneos a um recurso. Uma Lock pode ser inserida e encerrada, em que a região do código entre a entrada e a saída é uma seção crítica associada ao bloqueio. Um thread que insere um bloqueio é dito para manter ou possuir o bloqueio até que ele saia do bloqueio. No máximo, um thread pode manter um bloqueio a qualquer momento. Um thread pode conter vários bloqueios. Um thread pode inserir um bloqueio várias vezes antes de sair dele, como recursivamente. Um thread que não pode inserir um bloqueio imediatamente pode aguardar até que o bloqueio possa ser inserido ou até que um tempo limite especificado expire.

Ao usar os Enter métodos ou TryEnter para inserir um bloqueio:

  • Verifique se o thread sai do bloqueio mesmo Exit em caso de exceções, como em C# usando um try/finally bloco.
  • Quando o bloqueio estiver sendo inserido e encerrado em um método C# async , verifique se não há nenhum await entre a entrada e a saída. Os bloqueios são mantidos por threads e o código a seguir await pode ser executado em um thread diferente.

É recomendável usar o EnterScope método com um constructo de linguagem que descarta automaticamente o retornado Lock.Scope , como a palavra-chave C# using , ou usar a palavra-chave C# lock , pois eles garantem que o bloqueio seja encerrado em casos excepcionais. Esses padrões também podem ter benefícios de desempenho em vez de usar Enter/TryEnter e Exit. O fragmento de código a seguir ilustra vários padrões para entrar e sair de um bloqueio.

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 inserir e sair de um bloqueio, o tipo da expressão deve ser precisamente System.Threading.Lock. Se o tipo da expressão for qualquer outra coisa, como Object ou um tipo genérico como T, uma implementação diferente que não seja intercambiável poderá ser usada em vez disso (como Monitor). Para obter mais informações, consulte o espectro do compilador relevante.

Interrupt pode interromper threads que estão aguardando para inserir um bloqueio. Em Windows threads sta, esperas por bloqueios permitem o bombeamento de mensagens que podem executar outro código no mesmo thread durante uma espera. Alguns recursos das esperas podem ser substituídos por um personalizado SynchronizationContext.

Note

Um thread que insere um 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 insiram o bloqueio. Se um thread for encerrado durante a retenção de um Lock, o comportamento do Lock se tornará indefinido.

Caution

Se, em um caminho de código, um thread puder inserir vários bloqueios antes de sair deles, verifique se todos os caminhos de código que podem inserir dois desses bloqueios no mesmo thread os inserirão na mesma ordem. Caso contrário, isso pode levar a deadlocks. Por exemplo, considere que, em um thread T1 de caminho de código, insira o bloqueio L1 e bloqueie L2 antes de sair de ambos e, em outro thread T2 de caminho de código, insira ambos os bloqueios na ordem inversa. Nesse cenário, seria possível que a seguinte ordem de eventos ocorresse: insere, insereL2, T1 tenta entrar L2 e aguarda, T2 tenta entrar L1 e aguarda. T2L1T1 Há um deadlock entre T1 e T2 que não pode ser resolvido, e quaisquer outros threads que tentarem entrar em qualquer bloqueio no futuro também serão travados.

Construtores

Nome Description
Lock()

Inicializa uma nova instância da classe Lock.

Propriedades

Nome Description
IsHeldByCurrentThread

Obtém um valor que indica se o bloqueio é mantido pelo thread atual.

Métodos

Nome Description
Enter()

Insere o bloqueio, aguardando se necessário até que o bloqueio possa ser inserido.

EnterScope()

Insere o bloqueio, aguardando se necessário até que o bloqueio possa ser inserido.

Equals(Object)

Determina se o objeto especificado é igual ao objeto atual.

(Herdado de Object)
Exit()

Sai do bloqueio.

GetHashCode()

Serve como a função de hash padrão.

(Herdado de Object)
GetType()

Obtém o Type da instância atual.

(Herdado de Object)
MemberwiseClone()

Cria uma cópia superficial do Objectatual.

(Herdado de Object)
ToString()

Retorna uma cadeia de caracteres que representa o objeto atual.

(Herdado de Object)
TryEnter()

Tenta inserir o bloqueio sem esperar.

TryEnter(Int32)

Tenta inserir o bloqueio, aguardando se necessário o número especificado de milissegundos até que o bloqueio possa ser inserido.

TryEnter(TimeSpan)

Tenta inserir o bloqueio, aguardando se necessário até que o bloqueio possa ser inserido ou até que o tempo limite especificado expire.

Aplica-se a