Share via


ReaderWriterLockSlim.EnterUpgradeableReadLock Methode

Definition

Versucht, die Sperre im erweiterbaren Modus zu erhalten.

public:
 void EnterUpgradeableReadLock();
public void EnterUpgradeableReadLock ();
member this.EnterUpgradeableReadLock : unit -> unit
Public Sub EnterUpgradeableReadLock ()

Ausnahmen

Die RecursionPolicy-Eigenschaft ist NoRecursion, und dem aktuellen Thread wurde die Sperre bereits in einem der Modi zugewiesen.

- oder -

Der aktuelle Thread befindet sich im Lesemodus, sodass durch eine Zuweisung des erweiterbaren Modus die Möglichkeit eines Deadlocks entstehen würde.

- oder -

Die Anzahl von Rekursionen würde die Kapazität des Zählers überschreiten. Die Kapazität ist so groß, dass Anwendungen diese Grenze niemals erreichen dürften.

Das ReaderWriterLockSlim -Objekt wurde verworfen.

Beispiele

Das folgende Beispiel zeigt, wie Sie die EnterUpgradeableReadLock -Methode verwenden, um die Sperre im upgradefähigen Modus zu wechseln. Ein finally Block wird verwendet, um die ExitUpgradeableReadLock -Methode auszuführen, um sicherzustellen, dass der Aufrufer den upgradefähigen Modus beendet.

Die im Beispiel gezeigte Methode ruft den einem Schlüssel zugeordneten Wert ab und vergleicht ihn mit einem neuen Wert. Wenn der Wert unverändert ist, gibt die Methode eine status zurück, die keine Änderung angibt. Wenn kein Wert für den Schlüssel gefunden wird, wird das Schlüssel-Wert-Paar eingefügt. Wenn sich der Wert geändert hat, wird er aktualisiert. Der upgradebare Modus ermöglicht es dem Thread, die Lesesperre nach Bedarf ohne Deadlocks zu aktualisieren.

Im Beispiel wird der parameterlose Konstruktor verwendet, um die Sperre zu erstellen, sodass die Rekursion nicht zulässig ist. Das Programmieren von ReaderWriterLockSlim ist einfacher und weniger fehleranfällig, wenn die Sperre keine Rekursion zulässt.

Dieser Code ist Teil eines größeren Beispiels für die ReaderWriterLockSlim -Klasse.

private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
private Dictionary<int, string> innerCache = new Dictionary<int, string>();
Private cacheLock As New ReaderWriterLockSlim()
Private innerCache As New Dictionary(Of Integer, String)
public AddOrUpdateStatus AddOrUpdate(int key, string value)
{
    cacheLock.EnterUpgradeableReadLock();
    try
    {
        string result = null;
        if (innerCache.TryGetValue(key, out result))
        {
            if (result == value)
            {
                return AddOrUpdateStatus.Unchanged;
            }
            else
            {
                cacheLock.EnterWriteLock();
                try
                {
                    innerCache[key] = value;
                }
                finally
                {
                    cacheLock.ExitWriteLock();
                }
                return AddOrUpdateStatus.Updated;
            }
        }
        else
        {
            cacheLock.EnterWriteLock();
            try
            {
                innerCache.Add(key, value);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
            return AddOrUpdateStatus.Added;
        }
    }
    finally
    {
        cacheLock.ExitUpgradeableReadLock();
    }
}
Public Function AddOrUpdate(ByVal key As Integer, _
                            ByVal value As String) As AddOrUpdateStatus
    cacheLock.EnterUpgradeableReadLock()
    Try
        Dim result As String = Nothing
        If innerCache.TryGetValue(key, result) Then
            If result = value Then
                Return AddOrUpdateStatus.Unchanged
            Else
                cacheLock.EnterWriteLock()
                Try
                    innerCache.Item(key) = value
                Finally
                    cacheLock.ExitWriteLock()
                End Try
                Return AddOrUpdateStatus.Updated
            End If
        Else
            cacheLock.EnterWriteLock()
            Try
                innerCache.Add(key, value)
            Finally
                cacheLock.ExitWriteLock()
            End Try
            Return AddOrUpdateStatus.Added
        End If
    Finally
        cacheLock.ExitUpgradeableReadLock()
    End Try
End Function
public enum AddOrUpdateStatus
{
    Added,
    Updated,
    Unchanged
};
Public Enum AddOrUpdateStatus
    Added
    Updated
    Unchanged
End Enum

Hinweise

Diese Methode blockiert, bis der aufrufende Thread in die Sperre eintritt, und gibt daher möglicherweise nie zurück. Verwenden Sie die TryEnterUpgradeableReadLock -Methode, um für ein angegebenes Intervall zu blockieren, und geben Sie dann zurück, wenn der aufrufende Thread während dieses Intervalls nicht in den upgradebaren Modus eingetreten ist.

Verwenden Sie den upgradebaren Modus, wenn ein Thread normalerweise auf die Ressource zugreift, die im Lesemodus geschützt ist, aber möglicherweise in den ReaderWriterLockSlim Schreibmodus wechseln muss, wenn bestimmte Bedingungen erfüllt sind. Ein Thread im upgradebaren Modus kann ein Downgrade in den Lesemodus oder ein Upgrade auf den Schreibmodus durchführen.

Nur ein Thread kann jederzeit in den upgradebaren Modus wechseln. Wenn sich ein Thread im upgradefähigen Modus befindet und keine Threads darauf warten, in den Schreibmodus zu wechseln, kann eine beliebige Anzahl anderer Threads in den Lesemodus wechseln, auch wenn Threads darauf warten, in den upgradebaren Modus zu wechseln.

Wenn mindestens ein Thread darauf wartet, in den Schreibmodus zu wechseln, wird ein Thread, der die EnterUpgradeableReadLock -Methode aufruft, blockiert, bis diese Threads entweder zeitlimitiert oder in den Schreibmodus versetzt wurden und dann beendet wurde.

Hinweis

Wenn eine Sperre die Rekursion zulässt, kann ein Thread, der die Sperre im upgradebaren Modus betreten hat, rekursiv in den upgradebaren Modus wechseln, auch wenn andere Threads darauf warten, in den Schreibmodus zu wechseln.

Gilt für: