Lock Classe

Definição

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/finally bloco.
  • Quando a fechadura está a ser introduzida e saída num método C# async , certifique-se de que não await há espaço entre a entrada e a saída. Os bloqueios são mantidos por threads e o código que se segue await pode 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.

Aplica-se a