LockRecursionPolicy 枚举

定义

指定同一个线程是否可以多次进入一个锁定状态。

C#
public enum LockRecursionPolicy
继承
LockRecursionPolicy

字段

NoRecursion 0

如果线程尝试以递归方式进入锁定状态,将引发异常。 某些类可能会在此设置生效时允许使用特定的递归方式。

SupportsRecursion 1

线程可以采用递归方式进入锁定状态。 某些类可能会限制此功能。

示例

以下示例演示了两个异常方案,一个方案取决于 LockRecursionPolicy 设置,另一个方案不例外。

在第一种情况下,线程在读取模式下输入锁,然后尝试以递归方式进入读取模式。 ReaderWriterLockSlim如果使用无参数构造函数创建,它将递归策略设置为 NoRecursion,则会引发异常。 如果使用 SupportsRecursion 创建 ReaderWriterLockSlim,则不会引发异常。

第二种情况是,线程在读取模式下进入锁,然后尝试在写入模式下输入锁。 LockRecursionException 无论锁递归策略如何,都会引发。

C#
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.

注解

默认递归策略取决于锁的类型。 有关任何给定锁类型的默认策略和锁递归的精确行为,请参阅该类型的文档。 例如, ReaderWriterLockSlim 如果线程已在读取模式下进入锁(无论锁策略设置如何),则不允许线程在写入模式下输入锁,以减少死锁的可能性。

目前只有一个锁使用此枚举:

适用于

产品 版本
.NET Core 1.0, Core 1.1, Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7
.NET Framework 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8
.NET Standard 1.0, 1.1, 1.2, 1.3, 1.4, 1.6, 2.0, 2.1
UWP 10.0