Condividi tramite


Lock Classe

Definizione

Nota

Per usare questa API di anteprima, devi abilitare le funzionalità di anteprima nel progetto impostando la proprietà EnablePreviewFeatures su True nel file del progetto. Per altre informazioni, vedere https://aka.ms/dotnet-preview-features.

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

public ref class Lock sealed
[System.Runtime.Versioning.RequiresPreviewFeatures]
public sealed class Lock
[<System.Runtime.Versioning.RequiresPreviewFeatures>]
type Lock = class
Public NotInheritable Class Lock
Ereditarietà
Lock
Attributi

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 uscire, 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 vi sia tra await l'immissione e l'uscita. I blocchi vengono mantenuti dai thread e il codice seguente await può 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 garantiscono che il blocco venga chiuso in casi eccezionali. Questi modelli possono anche avere 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 altro elemento, ad esempio Object o un tipo generico come T, è possibile usare un'implementazione diversa che non è intercambiabile , ad esempio Monitor. Per altre informazioni, vedere la specifica del compilatore pertinente.

Interrupt può interrompere i thread in attesa di immettere un blocco. Nei thread STA di Windows, le attese per i blocchi consentono l'invio di messaggi che possono eseguire altro codice nello stesso thread durante un'attesa. Alcune funzionalità delle attese possono essere sostituite da un oggetto personalizzato SynchronizationContext.

Nota

Un thread che entra in un blocco, tra cui 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 tenendo premuto , Lockil comportamento dell'oggetto Lock diventa indefinito.

Attenzione

Se, in un percorso di codice, un thread potrebbe immettere più blocchi prima di uscire, 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 nel blocco L1 e quindi blocca L2 prima di uscire da entrambi e in un altro thread T2 del percorso di codice inserisce 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 tutti gli altri thread che tentano di immettere entrambi i blocchi in futuro si bloccano.

Costruttori

Lock()

Inizializza una nuova istanza della classe Lock.

Proprietà

IsHeldByCurrentThread

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

Metodi

Enter()

Entra nel blocco, in attesa, se necessario, fino a quando non è possibile immettere il blocco.

EnterScope()

Entra nel blocco, in attesa, se necessario, fino a quando non è possibile immettere il blocco.

Equals(Object)

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

(Ereditato da Object)
Exit()

Chiude il blocco.

GetHashCode()

Funge da funzione hash predefinita.

(Ereditato da Object)
GetType()

Ottiene l'oggetto Type dell'istanza corrente.

(Ereditato da Object)
MemberwiseClone()

Crea una copia superficiale dell'oggetto Object corrente.

(Ereditato da Object)
ToString()

Restituisce una stringa che rappresenta l'oggetto corrente.

(Ereditato da Object)
TryEnter()

Tenta di immettere il blocco senza attendere.

TryEnter(Int32)

Tenta di immettere il blocco, in attesa, se necessario, del numero specificato di millisecondi fino a quando non è possibile immettere il blocco.

TryEnter(TimeSpan)

Tenta di 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