Прочитать на английском

Поделиться через


LockRecursionPolicy Перечисление

Определение

Указывает, можно ли несколько раз войти в блокировку из одного и того же потока.

C#
public enum LockRecursionPolicy
Наследование
LockRecursionPolicy

Поля

NoRecursion 0

Если поток пытается войти в блокировку рекурсивно, выдается ошибка. Некоторые классы могут допускать определенные виды рекурсий при активированном параметре.

SupportsRecursion 1

Допускается рекурсивный вход потока в блокировку. Некоторые классы могут игнорировать эту возможность.

Примеры

В следующем примере показаны два сценария исключений: один из них зависит от параметра и другого LockRecursionPolicy .

В первом сценарии поток переходит в блокировку в режиме чтения, а затем пытается перейти в режим чтения рекурсивно. Если объект ReaderWriterLockSlim создается с помощью конструктора без параметров, который задает для политики рекурсии значение NoRecursion, возникает исключение. Если для создания ReaderWriterLockSlimиспользуется SupportsRecursion, исключение не возникает.

Во втором сценарии поток переходит в блокировку в режиме чтения, а затем пытается войти в блокировку в режиме записи. 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