Udostępnij za pośrednictwem


ReaderWriterLockSlim.EnterUpgradeableReadLock Metoda

Definicja

Próbuje wprowadzić blokadę w trybie uaktualniania.

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

Wyjątki

Właściwość RecursionPolicy jest NoRecursion i bieżący wątek już wprowadził blokadę w dowolnym trybie.

-lub-

Bieżący wątek został wprowadzony w tryb odczytu, więc próba wprowadzenia trybu uaktualniania spowodowałoby możliwość zakleszczenia.

-lub-

Liczba rekursji przekroczyłaby pojemność licznika. Limit jest tak duży, że aplikacje nigdy nie powinny go napotkać.

Obiekt ReaderWriterLockSlim został usunięty.

Przykłady

W poniższym przykładzie pokazano, jak za pomocą EnterUpgradeableReadLock metody wprowadzić blokadę w trybie uaktualniania. Blok finally służy do wykonywania ExitUpgradeableReadLock metody, zapewniając, że obiekt wywołujący kończy tryb uaktualniania.

Metoda pokazana w przykładzie pobiera wartość skojarzona z kluczem i porównuje ją z nową wartością. Jeśli wartość jest niezmieniona, metoda zwraca stan wskazujący brak zmian. Jeśli dla klucza nie zostanie znaleziona żadna wartość, zostanie wstawiona para klucz/wartość. Jeśli wartość została zmieniona, zostanie ona zaktualizowana. Tryb uaktualniania umożliwia wątkowi uaktualnienie blokady odczytu zgodnie z potrzebami bez ryzyka zakleszczenia.

W przykładzie użyto konstruktora bez parametrów do utworzenia blokady, więc rekursja nie jest dozwolona. Programowanie jest ReaderWriterLockSlim prostsze i mniej podatne na błąd, gdy blokada nie zezwala na rekursję.

Ten kod jest częścią większego przykładu udostępnionego ReaderWriterLockSlim dla klasy .

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

Uwagi

Ta metoda blokuje, dopóki wątek wywołujący nie wejdzie do blokady i dlatego nigdy nie powróci. TryEnterUpgradeableReadLock Użyj metody , aby zablokować określony interwał, a następnie zwrócić, jeśli w danym interwale nie wprowadzono trybu uaktualniania wywołującego wątku.

Użyj trybu uaktualniania, gdy wątek zwykle uzyskuje dostęp do zasobu chronionego ReaderWriterLockSlim w trybie odczytu, ale może być konieczne wprowadzenie trybu zapisu, jeśli zostaną spełnione określone warunki. Wątek w trybie uaktualniania może obniżyć wersję do trybu odczytu lub uaktualnić do trybu zapisu.

W danym momencie tylko jeden wątek może wejść w tryb uaktualniania. Jeśli wątek jest w trybie uaktualniania i nie ma wątków oczekujących na przejście do trybu zapisu, dowolna liczba innych wątków może wejść w tryb odczytu, nawet jeśli wątki oczekują na przejście w tryb możliwy do uaktualnienia.

Jeśli co najmniej jeden wątek oczekuje na wejście w tryb zapisu, wątek, który wywołuje EnterUpgradeableReadLock bloki metody, dopóki te wątki nie upłynął limit czasu lub wszedł w tryb zapisu, a następnie wyszedł z niego.

Uwaga

Jeśli blokada zezwala na rekursję, wątek, który wprowadził blokadę w trybie uaktualniania, może cyklicznie przejść w tryb uaktualniania, nawet jeśli inne wątki czekają na przejście do trybu zapisu.

Dotyczy