Lock Classe

Definizione

Fornisce un meccanismo per ottenere l'esclusione reciproca nelle aree di codice tra thread diversi.

public ref class Lock sealed
public sealed class Lock
type Lock = class
Public NotInheritable Class Lock
Ereditarietà
Lock

Commenti

La Lock classe può essere usata per definire aree di codice che richiedono l'accesso reciproco esclusivo tra thread di un processo, comunemente denominate sezioni critiche, per impedire accessi simultanei a una risorsa. Un Lock oggetto può essere immesso e chiuso, in cui l'area di codice tra l'immissione e l'uscita è una sezione critica associata al blocco. Un thread che entra in un blocco viene detto tenere o possedere il blocco fino a quando non esce dal blocco. Al massimo un thread può contenere un blocco in qualsiasi momento. Un thread può contenere più blocchi. Un thread può entrare più volte in un blocco prima di chiuderlo, ad esempio in modo ricorsivo. Un thread che non può immettere un blocco immediatamente può attendere fino a quando il blocco non può essere immesso o fino alla scadenza di un timeout specificato.

Quando si usano i Enter metodi o TryEnter per immettere un blocco:

  • Assicurarsi che il thread esce dal blocco anche Exit in caso di eccezioni, ad esempio in C# usando un try/finally blocco.
  • Quando il blocco viene immesso e chiuso in un metodo C# async , assicurarsi che non await vi sia tra l'ingresso e l'uscita. I blocchi vengono mantenuti dai thread e il codice seguente await potrebbe essere eseguito in un thread diverso.

È consigliabile usare il EnterScope metodo con un costrutto di linguaggio che elimina automaticamente l'oggetto restituito Lock.Scope , ad esempio la parola chiave C# using o per usare la parola chiave C# lock , in quanto assicurano che il blocco venga chiuso in casi eccezionali. Questi modelli possono avere anche vantaggi in termini di prestazioni rispetto all'uso Enter/TryEnter di e Exit. Il frammento di codice seguente illustra vari modelli per l'immissione e l'uscita di un blocco.

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(); }
        }
    }
}

Quando si usa la parola chiave C# lock o simile a immettere e uscire da un blocco, il tipo dell'espressione deve essere esattamente System.Threading.Lock. Se il tipo dell'espressione è qualsiasi altra cosa, ad esempio Object o un tipo generico come T, è possibile usare un'implementazione diversa che non è intercambiabile, ad esempio Monitor. Per altre informazioni, vedere lo speclet del compilatore pertinente.

Interrupt può interrompere i thread in attesa di immettere un blocco. In Windows thread STA, le attese per i blocchi consentono il pumping dei messaggi che può eseguire altro codice nello stesso thread durante un'attesa. Alcune funzionalità delle attese possono essere sottoposte a override da un oggetto personalizzato SynchronizationContext.

Note

Un thread che entra in un blocco, incluso più volte, ad esempio in modo ricorsivo, deve uscire dal blocco lo stesso numero di volte per uscire completamente dal blocco e consentire ad altri thread di entrare nel blocco. Se un thread viene chiuso mentre si tiene un oggetto Lock, il comportamento dell'oggetto Lock diventa indefinito.

Caution

Se, in un percorso di codice, un thread potrebbe immettere più blocchi prima di chiuderli, assicurarsi che tutti i percorsi di codice che potrebbero immettere uno qualsiasi di questi blocchi nello stesso thread li immettono nello stesso ordine. In caso contrario, potrebbe causare deadlock. Si consideri, ad esempio, che in un thread T1 di percorso del codice entra in blocco L1 e quindi blocca L2 prima di uscire da entrambi e in un altro thread T2 di percorso del codice vengono immessi entrambi i blocchi nell'ordine inverso. In questo scenario, sarebbe possibile che si verifichi l'ordine di eventi seguente: T1 immette , T2 immette L1L2, T1 tenta di immettere L2 e attendere, T2 tenta di immettere L1 e attendere. C'è un deadlock tra T1 e T2 che non può essere risolto e anche qualsiasi altro thread che tenta di immettere uno dei due blocchi in futuro si blocca.

Costruttori

Nome Descrizione
Lock()

Inizializza una nuova istanza della classe Lock.

Proprietà

Nome Descrizione
IsHeldByCurrentThread

Ottiene un valore che indica se il blocco viene mantenuto dal thread corrente.

Metodi

Nome Descrizione
Enter()

Entra nel blocco, in attesa, se necessario, fino a quando il blocco non può essere immesso.

EnterScope()

Entra nel blocco, in attesa, se necessario, fino a quando il blocco non può essere immesso.

Equals(Object)

Determina se l'oggetto specificato è uguale all'oggetto corrente.

(Ereditato da Object)
Exit()

Esce dal blocco.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetType()

Ottiene il Type dell'istanza corrente.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale del Objectcorrente.

(Ereditato da Object)
ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)
TryEnter()

Prova a immettere il blocco senza attendere.

TryEnter(Int32)

Prova a immettere il blocco, in attesa, se necessario, del numero specificato di millisecondi fino all'immissione del blocco.

TryEnter(TimeSpan)

Prova a immettere il blocco, in attesa, se necessario, fino a quando il blocco non può essere immesso o fino alla scadenza del timeout specificato.

Si applica a