Freigeben über


LockRecursionPolicy Enumeration

Definition

Gibt an, ob eine Sperre mehrmals durch denselben Thread eingegeben werden kann.

public enum class LockRecursionPolicy
public enum LockRecursionPolicy
type LockRecursionPolicy = 
Public Enum LockRecursionPolicy
Vererbung
LockRecursionPolicy

Felder

Name Wert Beschreibung
NoRecursion 0

Wenn ein Thread versucht, eine Sperre rekursiv einzugeben, wird eine Ausnahme ausgelöst. Einige Klassen können bestimmte Rekursionen zulassen, wenn diese Einstellung wirksam ist.

SupportsRecursion 1

Ein Thread kann rekursiv eine Sperre eingeben. Einige Klassen können diese Funktion einschränken.

Beispiele

Das folgende Beispiel zeigt zwei Ausnahmeszenarien, eines, das von der LockRecursionPolicy Einstellung abhängt, und eines, das nicht.

Im ersten Szenario wechselt der Thread in den Lesemodus und versucht dann rekursiv in den Lesemodus zu wechseln. Wenn die ReaderWriterLockSlim Methode mithilfe des parameterlosen Konstruktors erstellt wird, der die Rekursionsrichtlinie auf "NoRecursion" festlegt, wird eine Ausnahme ausgelöst. Wenn SupportsRecursion zum Erstellen des ReaderWriterLockSlimSupports verwendet wird, wird keine Ausnahme ausgelöst.

Im zweiten Szenario wechselt der Thread in den Lesemodus und versucht dann, die Sperre im Schreibmodus einzugeben. LockRecursionException wird unabhängig von der Sperr-Rekursionsrichtlinie ausgelöst.

using System;
using System.Threading;

class Example
{
    // By default, the lock recursion policy for a new 
    // ReaderWriterLockSlim does not allow recursion.
    private static ReaderWriterLockSlim rwls = new ReaderWriterLockSlim();
    private static ReaderWriterLockSlim rwlsWithRecursion =
        new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);

    static void ThreadProc()
    { 
        Console.WriteLine("1. Enter the read lock recursively.");
        ReadRecursive(rwls);
        ReadRecursive(rwlsWithRecursion);

        Console.WriteLine("\n2. Enter the write lock recursively from the read lock.");
        ReadWriteRecursive(rwls);
        ReadWriteRecursive(rwlsWithRecursion);
    } 

    static void ReadRecursive(ReaderWriterLockSlim rwls)
    {
        Console.WriteLine("LockRecursionPolicy.{0}:", rwls.RecursionPolicy);
        rwls.EnterReadLock();

        try {
            rwls.EnterReadLock();
            Console.WriteLine("\nThe read lock was entered recursively.");
            rwls.ExitReadLock();
        }    
        catch (LockRecursionException lre) {
            Console.WriteLine("\n{0}: {1}",
                lre.GetType().Name, lre.Message);
        }

        rwls.ExitReadLock();
    }

    static void ReadWriteRecursive(ReaderWriterLockSlim rwls)
    {
        Console.WriteLine("LockRecursionPolicy.{0}:", rwls.RecursionPolicy);
        rwls.EnterReadLock();

        try {
            rwls.EnterWriteLock();
            Console.WriteLine("\nThe write lock was entered recursively.");
        }
        catch (LockRecursionException lre) {
            Console.WriteLine("\n{0}: {1}", 
                lre.GetType().Name, lre.Message);
        }

        rwls.ExitReadLock();
    }

    static void Main() 
    {
        Thread t = new Thread(ThreadProc);
        t.Start();
        t.Join();
        
        // Dispose of ReaderWriterLockSlim objects' unmanaged resources.
        if (rwls != null) rwls.Dispose();
        if (rwlsWithRecursion != null) rwlsWithRecursion.Dispose();
    } 
} 
// This example displays output similar to the following:
//    1. Enter the read lock recursively.
//    LockRecursionPolicy.NoRecursion:
//    
//    LockRecursionException: Recursive read lock acquisitions not allowed in this mode.
//    LockRecursionPolicy.SupportsRecursion:
//    
//    The read lock was entered recursively.
//    
//    2. Enter the write lock recursively from the read lock.
//    LockRecursionPolicy.NoRecursion:
//    
//    LockRecursionException: Write lock may not be acquired with read lock held. This pattern i
//    s prone to deadlocks. Please ensure that read locks are released before taking a write loc
//    k. If an upgrade is necessary, use an upgrade lock in place of the read lock.
//    LockRecursionPolicy.SupportsRecursion:
//    
//    LockRecursionException: Write lock may not be acquired with read lock held. This pattern i
//    s prone to deadlocks. Please ensure that read locks are released before taking a write loc
//    k. If an upgrade is necessary, use an upgrade lock in place of the read lock.
Imports System.Threading

Class Example
    ' By default, the lock recursion policy for a new 
    ' ReaderWriterLockSlim does not allow recursion.
    Private Shared rwls As New ReaderWriterLockSlim()
    Private Shared rwlsWithRecursion _
        As New ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion)
    
    Shared Sub ThreadProc() 
        
        Console.WriteLine("1. Enter the read lock recursively.")
        ReadRecursive(rwls)
        ReadRecursive(rwlsWithRecursion)
    
        Console.WriteLine(vbCrLf & _
            "2. Enter the write lock recursively from the read lock.")
        ReadWriteRecursive(rwls)
        ReadWriteRecursive(rwlsWithRecursion)

    End Sub 

    Shared Sub ReadRecursive(ByVal rwls As ReaderWriterLockSlim)

        Console.WriteLine("LockRecursionPolicy.{0}:", rwls.RecursionPolicy)
        rwls.EnterReadLock()
        
        Try
            rwls.EnterReadLock()
            Console.WriteLine(vbTab & _
                "The read lock was entered recursively.")
            rwls.ExitReadLock()
        Catch lre As LockRecursionException
            Console.WriteLine(vbTab & "{0}: {1}", _
                lre.GetType().Name, lre.Message)
        End Try

        rwls.ExitReadLock()
    End Sub

    Shared Sub ReadWriteRecursive(ByVal rwls As ReaderWriterLockSlim)

        Console.WriteLine("LockRecursionPolicy.{0}:", rwls.RecursionPolicy)
        rwls.EnterReadLock()

        Try
            rwls.EnterWriteLock()
            Console.WriteLine(vbTab & _
                "The write lock was entered recursively.")
        Catch lre As LockRecursionException
            Console.WriteLine(vbTab & "{0}: {1}", _
                lre.GetType().Name, lre.Message)
        End Try

        rwls.ExitReadLock()
    End Sub
    
    Shared Sub Main() 

        Dim t As New Thread(AddressOf ThreadProc)
        t.Start()
        t.Join()

        ' Dispose of ReaderWriterLockSlim objects' unmanaged resources.
        If rwls IsNot Nothing Then rwls.Dispose()
        If rwlsWithRecursion IsNot Nothing Then _
           rwlsWithRecursion.Dispose()
    End Sub 
End Class 

' This code example produces output similar to the following:
'
'1. Enter the read lock recursively.
'LockRecursionPolicy.NoRecursion:
'        LockRecursionException: Recursive read lock acquisitions not allowed in this mode.
'LockRecursionPolicy.SupportsRecursion:
'        The read lock was entered recursively.
'
'2. Enter the write lock recursively from the read lock.
'LockRecursionPolicy.NoRecursion:
'        LockRecursionException: Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Consider using the upgrade lock.
'LockRecursionPolicy.SupportsRecursion:
'        LockRecursionException: Write lock may not be acquired with read lock held. This pattern is prone to deadlocks. Consider using the upgrade lock.
'

Hinweise

Die Standardmäßige Rekursionsrichtlinie hängt vom Typ der Sperre ab. Die Standardrichtlinie und das genaue Verhalten der Sperrrekkursion für einen bestimmten Sperrtyp finden Sie in der Dokumentation für den Typ. Die Klasse lässt beispielsweise nicht zu, ReaderWriterLockSlim dass ein Thread die Sperre im Schreibmodus eingibt, wenn er die Sperre bereits im Lesemodus eingegeben hat, unabhängig von der Sperrrichtlinieneinstellung, um die Wahrscheinlichkeit von Deadlocks zu verringern.

Derzeit verwendet nur eine Sperre diese Enumeration:

Gilt für: