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