ReaderWriterLockSlim ReaderWriterLockSlim ReaderWriterLockSlim ReaderWriterLockSlim Class

Definition

Stellt eine Sperre dar, mit der der Zugriff auf eine Ressource verwaltet wird. Mehrere Threads können damit Lesezugriff oder exklusiven Schreibzugriff erhalten.Represents a lock that is used to manage access to a resource, allowing multiple threads for reading or exclusive access for writing.

public ref class ReaderWriterLockSlim : IDisposable
public class ReaderWriterLockSlim : IDisposable
type ReaderWriterLockSlim = class
    interface IDisposable
Public Class ReaderWriterLockSlim
Implements IDisposable
Vererbung
ReaderWriterLockSlimReaderWriterLockSlimReaderWriterLockSlimReaderWriterLockSlim
Implementiert

Beispiele

Das folgende Beispiel zeigt einen einfachen synchronisierten Cache, der Zeichenfolgen mit ganzzahligen Schlüssel enthält.The following example shows a simple synchronized cache that holds strings with integer keys. Eine Instanz von ReaderWriterLockSlim wird zum Synchronisieren des Zugriffs auf die Dictionary<TKey,TValue> , die als interner Cache fungiert.An instance of ReaderWriterLockSlim is used to synchronize access to the Dictionary<TKey,TValue> that serves as the inner cache.

Das Beispiel enthält einfache Methoden, um dem Cache hinzuzufügen, aus dem Cache löschen und aus dem Cache gelesen.The example includes simple methods to add to the cache, delete from the cache, and read from the cache. Um zeitüberschreitungen zu demonstrieren, umfasst das Beispiel eine Methode, die mit dem Cache hinzugefügt werden soll, nur dann, wenn sie dies in einem angegebenen Timeout ausführen kann.To demonstrate time-outs, the example includes a method that adds to the cache only if it can do so within a specified time-out.

Um die Zuweisung des erweiterbaren Modus zu demonstrieren, wird im Beispiel enthält eine Methode, die den Wert eines Schlüssels abruft und vergleicht ihn mit einem neuen Wert.To demonstrate upgradeable mode, the example includes a method that retrieves the value associated with a key and compares it with a new value. Wenn der Wert unverändert ist, gibt die Methode einen Status, der angibt, der keine Änderung an.If the value is unchanged, the method returns a status indicating no change. Wenn kein Wert für den Schlüssel gefunden wird, wird der Schlüssel/Wert-Paar eingefügt.If no value is found for the key, the key/value pair is inserted. Wenn der Wert geändert wurde, wird er aktualisiert.If the value has changed, it is updated. Im erweiterbaren Modus kann der Thread von Lesezugriff auf den Zugriff zu schreiben, ohne das Risiko von Deadlocks bei Bedarf aktualisieren.Upgradeable mode allows the thread to upgrade from read access to write access as needed, without the risk of deadlocks.

Das Beispiel enthält eine geschachtelte-Enumeration, die die Rückgabewerte für die Methode gibt an, die Zuweisung des erweiterbaren Modus veranschaulicht.The example includes a nested enumeration that specifies the return values for the method that demonstrates upgradeable mode.

Im Beispiel wird den Standardkonstruktor die Sperre zu erstellen, um die Rekursion nicht zulässig ist.The example uses the default constructor to create the lock, so recursion is not allowed. Programmierung der ReaderWriterLockSlim einfacher und weniger fehleranfällig ist, wenn die Sperre Rekursion nicht möglich ist.Programming the ReaderWriterLockSlim is simpler and less prone to error when the lock does not allow recursion.

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
public class SynchronizedCache 
{
    private ReaderWriterLockSlim cacheLock = new ReaderWriterLockSlim();
    private Dictionary<int, string> innerCache = new Dictionary<int, string>();

    public int Count
    { get { return innerCache.Count; } }

    public string Read(int key)
    {
        cacheLock.EnterReadLock();
        try
        {
            return innerCache[key];
        }
        finally
        {
            cacheLock.ExitReadLock();
        }
    }

    public void Add(int key, string value)
    {
        cacheLock.EnterWriteLock();
        try
        {
            innerCache.Add(key, value);
        }
        finally
        {
            cacheLock.ExitWriteLock();
        }
    }

    public bool AddWithTimeout(int key, string value, int timeout)
    {
        if (cacheLock.TryEnterWriteLock(timeout))
        {
            try
            {
                innerCache.Add(key, value);
            }
            finally
            {
                cacheLock.ExitWriteLock();
            }
            return true;
        }
        else
        {
            return false;
        }
    }

    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 void Delete(int key)
    {
        cacheLock.EnterWriteLock();
        try
        {
            innerCache.Remove(key);
        }
        finally
        {
            cacheLock.ExitWriteLock();
        }
    }

    public enum AddOrUpdateStatus
    {
        Added,
        Updated,
        Unchanged
    };

    ~SynchronizedCache()
    {
       if (cacheLock != null) cacheLock.Dispose();
    }
}
Public Class SynchronizedCache
    Private cacheLock As New ReaderWriterLockSlim()
    Private innerCache As New Dictionary(Of Integer, String)

    Public ReadOnly Property Count As Integer
       Get
          Return innerCache.Count
       End Get
    End Property
    
    Public Function Read(ByVal key As Integer) As String
        cacheLock.EnterReadLock()
        Try
            Return innerCache(key)
        Finally
            cacheLock.ExitReadLock()
        End Try
    End Function

    Public Sub Add(ByVal key As Integer, ByVal value As String)
        cacheLock.EnterWriteLock()
        Try
            innerCache.Add(key, value)
        Finally
            cacheLock.ExitWriteLock()
        End Try
    End Sub

    Public Function AddWithTimeout(ByVal key As Integer, ByVal value As String, _
                                   ByVal timeout As Integer) As Boolean
        If cacheLock.TryEnterWriteLock(timeout) Then
            Try
                innerCache.Add(key, value)
            Finally
                cacheLock.ExitWriteLock()
            End Try
            Return True
        Else
            Return False
        End If
    End Function

    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 Sub Delete(ByVal key As Integer)
        cacheLock.EnterWriteLock()
        Try
            innerCache.Remove(key)
        Finally
            cacheLock.ExitWriteLock()
        End Try
    End Sub

    Public Enum AddOrUpdateStatus
        Added
        Updated
        Unchanged
    End Enum

    Protected Overrides Sub Finalize()
       If cacheLock IsNot Nothing Then cacheLock.Dispose()
    End Sub
End Class

Der folgende code verwendet dann die SynchronizedCache Objekt, das ein Wörterbuch von vegetable Namen gespeichert.The following code then uses the SynchronizedCache object to store a dictionary of vegetable names. Es werden drei Aufgaben erstellt.It creates three tasks. Die erste schreibt die Namen der Gemüse gespeichert, die in einem Array auf einem SynchronizedCache Instanz.The first writes the names of vegetables stored in an array to a SynchronizedCache instance. Die zweite und dritte Aufgabe werden die Namen der Gemüse, die erste in aufsteigender Reihenfolge (von niedrigen Index hoher Index), das zweite in absteigender Reihenfolge anzeigen.The second and third task display the names of the vegetables, the first in ascending order (from low index to high index), the second in descending order. Die letzte Aufgabe sucht nach der Zeichenfolge "Cucumber", und wenn es gefunden wird, ruft der EnterUpgradeableReadLock Methode, um die Zeichenfolge "grüne Bean" zu ersetzen.The final task searches for the string "cucumber" and, when it finds it, calls the EnterUpgradeableReadLock method to substitute the string "green bean".

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks
public class Example
{
   public static void Main()
   {
      var sc = new SynchronizedCache();
      var tasks = new List<Task>();
      int itemsWritten = 0;

      // Execute a writer.
      tasks.Add(Task.Run( () => { String[] vegetables = { "broccoli", "cauliflower",
                                                          "carrot", "sorrel", "baby turnip",
                                                          "beet", "brussel sprout",
                                                          "cabbage", "plantain",
                                                          "spinach", "grape leaves",
                                                          "lime leaves", "corn",
                                                          "radish", "cucumber",
                                                          "raddichio", "lima beans" };
                                  for (int ctr = 1; ctr <= vegetables.Length; ctr++)
                                     sc.Add(ctr, vegetables[ctr - 1]);

                                  itemsWritten = vegetables.Length;
                                  Console.WriteLine("Task {0} wrote {1} items\n",
                                                    Task.CurrentId, itemsWritten);
                                } ));
      // Execute two readers, one to read from first to last and the second from last to first.
      for (int ctr = 0; ctr <= 1; ctr++) {
         bool desc = Convert.ToBoolean(ctr);
         tasks.Add(Task.Run( () => { int start, last, step;
                                     int items;
                                     do {
                                        String output = String.Empty;
                                        items = sc.Count;
                                        if (! desc) {
                                           start = 1;
                                           step = 1;
                                           last = items;
                                        }
                                        else {
                                           start = items;
                                           step = -1;
                                           last = 1;
                                        }

                                        for (int index = start; desc ? index >= last : index <= last; index += step)
                                           output += String.Format("[{0}] ", sc.Read(index));

                                        Console.WriteLine("Task {0} read {1} items: {2}\n",
                                                          Task.CurrentId, items, output);
                                     } while (items < itemsWritten | itemsWritten == 0);
                             } ));
      }
      // Execute a red/update task.
      tasks.Add(Task.Run( () => { Thread.Sleep(100);
                                  for (int ctr = 1; ctr <= sc.Count; ctr++) {
                                     String value = sc.Read(ctr);
                                     if (value == "cucumber")
                                        if (sc.AddOrUpdate(ctr, "green bean") != SynchronizedCache.AddOrUpdateStatus.Unchanged)
                                           Console.WriteLine("Changed 'cucumber' to 'green bean'");
                                  }
                                } ));

      // Wait for all three tasks to complete.
      Task.WaitAll(tasks.ToArray());

      // Display the final contents of the cache.
      Console.WriteLine();
      Console.WriteLine("Values in synchronized cache: ");
      for (int ctr = 1; ctr <= sc.Count; ctr++)
         Console.WriteLine("   {0}: {1}", ctr, sc.Read(ctr));

   }
}
// The example displays the following output:
//    Task 1 read 0 items:
//
//    Task 3 wrote 17 items
//
//
//    Task 1 read 17 items: [broccoli] [cauliflower] [carrot] [sorrel] [baby turnip] [
//    beet] [brussel sprout] [cabbage] [plantain] [spinach] [grape leaves] [lime leave
//    s] [corn] [radish] [cucumber] [raddichio] [lima beans]
//
//    Task 2 read 0 items:
//
//    Task 2 read 17 items: [lima beans] [raddichio] [cucumber] [radish] [corn] [lime
//    leaves] [grape leaves] [spinach] [plantain] [cabbage] [brussel sprout] [beet] [b
//    aby turnip] [sorrel] [carrot] [cauliflower] [broccoli]
//
//    Changed 'cucumber' to 'green bean'
//
//    Values in synchronized cache:
//       1: broccoli
//       2: cauliflower
//       3: carrot
//       4: sorrel
//       5: baby turnip
//       6: beet
//       7: brussel sprout
//       8: cabbage
//       9: plantain
//       10: spinach
//       11: grape leaves
//       12: lime leaves
//       13: corn
//       14: radish
//       15: green bean
//       16: raddichio
//       17: lima beans
Public Module Example
   Public Sub Main()
      Dim sc As New SynchronizedCache()
      Dim tasks As New List(Of Task)
      Dim itemsWritten As Integer
      
      ' Execute a writer.
      tasks.Add(Task.Run( Sub()
                             Dim vegetables() As String = { "broccoli", "cauliflower",
                                                            "carrot", "sorrel", "baby turnip",
                                                            "beet", "brussel sprout",
                                                            "cabbage", "plantain",
                                                            "spinach", "grape leaves",
                                                            "lime leaves", "corn",
                                                            "radish", "cucumber",
                                                            "raddichio", "lima beans" }
                             For ctr As Integer = 1 to vegetables.Length
                                sc.Add(ctr, vegetables(ctr - 1))
                             Next
                             itemsWritten = vegetables.Length
                             Console.WriteLine("Task {0} wrote {1} items{2}",
                                               Task.CurrentId, itemsWritten, vbCrLf)
                          End Sub))
      ' Execute two readers, one to read from first to last and the second from last to first.
      For ctr As Integer = 0 To 1
         Dim flag As Integer = ctr
         tasks.Add(Task.Run( Sub()
                                Dim start, last, stp As Integer
                                Dim items As Integer
                                Do
                                   Dim output As String = String.Empty
                                   items = sc.Count
                                   If flag = 0 Then
                                      start = 1 : stp = 1 : last = items
                                   Else
                                      start = items : stp = -1 : last = 1
                                   End If
                                   For index As Integer = start To last Step stp
                                      output += String.Format("[{0}] ", sc.Read(index))
                                   Next
                                   Console.WriteLine("Task {0} read {1} items: {2}{3}",
                                                           Task.CurrentId, items, output,
                                                           vbCrLf)
                                Loop While items < itemsWritten Or itemsWritten = 0
                             End Sub))
      Next
      ' Execute a red/update task.
      tasks.Add(Task.Run( Sub()
                             For ctr As Integer = 1 To sc.Count
                                Dim value As String = sc.Read(ctr)
                                If value = "cucumber" Then
                                   If sc.AddOrUpdate(ctr, "green bean") <> SynchronizedCache.AddOrUpdateStatus.Unchanged Then
                                      Console.WriteLine("Changed 'cucumber' to 'green bean'")
                                   End If
                                End If
                             Next
                          End Sub ))

      ' Wait for all three tasks to complete.
      Task.WaitAll(tasks.ToArray())

      ' Display the final contents of the cache.
      Console.WriteLine()
      Console.WriteLine("Values in synchronized cache: ")
      For ctr As Integer = 1 To sc.Count
         Console.WriteLine("   {0}: {1}", ctr, sc.Read(ctr))
      Next
   End Sub
End Module
' The example displays output like the following:
'    Task 1 read 0 items:
'
'    Task 3 wrote 17 items
'
'    Task 1 read 17 items: [broccoli] [cauliflower] [carrot] [sorrel] [baby turnip] [
'    beet] [brussel sprout] [cabbage] [plantain] [spinach] [grape leaves] [lime leave
'    s] [corn] [radish] [cucumber] [raddichio] [lima beans]
'
'    Task 2 read 0 items:
'
'    Task 2 read 17 items: [lima beans] [raddichio] [cucumber] [radish] [corn] [lime
'    leaves] [grape leaves] [spinach] [plantain] [cabbage] [brussel sprout] [beet] [b
'    aby turnip] [sorrel] [carrot] [cauliflower] [broccoli]
'
'    Changed 'cucumber' to 'green bean'
'
'    Values in synchronized cache:
'       1: broccoli
'       2: cauliflower
'       3: carrot
'       4: sorrel
'       5: baby turnip
'       6: beet
'       7: brussel sprout
'       8: cabbage
'       9: plantain
'       10: spinach
'       11: grape leaves
'       12: lime leaves
'       13: corn
'       14: radish
'       15: green bean
'       16: raddichio
'       17: lima beans

Hinweise

Verwendung ReaderWriterLockSlim zum Schützen einer Ressource, die von mehreren Threads gelesen und in einem Thread gleichzeitig geschrieben.Use ReaderWriterLockSlim to protect a resource that is read by multiple threads and written to by one thread at a time. ReaderWriterLockSlim ermöglicht mehreren Threads, die sich im Lesemodus befindet, ermöglicht es einem Thread im Schreibmodus mit exklusiven Besitz der Sperre sein und es einem Thread ermöglicht, die Lesezugriff auf die im erweiterbaren Modus zu lesen, werden von dem der Thread den Schreibmodus, ohne dass sie dafür aktualisieren können s Lesezugriff auf die Ressource an.ReaderWriterLockSlim allows multiple threads to be in read mode, allows one thread to be in write mode with exclusive ownership of the lock, and allows one thread that has read access to be in upgradeable read mode, from which the thread can upgrade to write mode without having to relinquish its read access to the resource.

Hinweis

ReaderWriterLockSlim ähnelt ReaderWriterLock, verfügt aber über vereinfachte Regeln für Rekursion sowie für Upgrade und Downgrade des Sperrstatus.ReaderWriterLockSlim is similar to ReaderWriterLock, but it has simplified rules for recursion and for upgrading and downgrading lock state. ReaderWriterLockSlim vermeidet viele potenzielle Deadlocks.ReaderWriterLockSlim avoids many cases of potential deadlock. Darüber hinaus ist die Leistung von ReaderWriterLockSlim wesentlich besser als die von ReaderWriterLock.In addition, the performance of ReaderWriterLockSlim is significantly better than ReaderWriterLock. ReaderWriterLockSlim wird für alle Neuentwicklungen empfohlen.ReaderWriterLockSlim is recommended for all new development.

Standardmäßig werden neue Instanzen von ReaderWriterLockSlim werden erstellt, mit der LockRecursionPolicy.NoRecursion kennzeichnen und Rekursion nicht zulassen.By default, new instances of ReaderWriterLockSlim are created with the LockRecursionPolicy.NoRecursion flag and do not allow recursion. Diese Standardrichtlinie wird für alle Neuentwicklungen empfohlen, da Rekursion unnötige Komplikationen eingeführt und wird Ihr Code anfälliger für Deadlocks.This default policy is recommended for all new development, because recursion introduces unnecessary complications and makes your code more prone to deadlocks. Zur Vereinfachung der Migration von vorhandenen Projekten, in denen Monitor oder ReaderWriterLock, können Sie die LockRecursionPolicy.SupportsRecursion Flag zum Erstellen von Instanzen der ReaderWriterLockSlim , mit denen Rekursion.To simplify migration from existing projects that use Monitor or ReaderWriterLock, you can use the LockRecursionPolicy.SupportsRecursion flag to create instances of ReaderWriterLockSlim that allow recursion.

Ein Thread kann die Sperre eingeben, in drei Modi: Modus Schreibmodus und Lesen im erweiterbaren Modus zu lesen.A thread can enter the lock in three modes: read mode, write mode, and upgradeable read mode. (Im weiteren Verlauf dieses Themas, "erweiterbaren Lesemodus" wird bezeichnet als "erweiterbaren Modus" aus, und der Ausdruck "Geben Sie x im Modus" wird verwendet, statt den längeren Ausdruck "Geben Sie die Sperre im x im Modus".)(In the rest of this topic, "upgradeable read mode" is referred to as "upgradeable mode", and the phrase "enter x mode" is used in preference to the longer phrase "enter the lock in x mode".)

Unabhängig von die Rekursionsrichtlinie für die kann nur ein Thread im Schreibmodus zu einem beliebigen Zeitpunkt sein.Regardless of recursion policy, only one thread can be in write mode at any time. Wenn ein Thread im Schreibmodus befindet, kann kein anderer Thread die Sperre in einem anderen Modus eingeben.When a thread is in write mode, no other thread can enter the lock in any mode. Nur ein Thread kann jederzeit im erweiterbaren Modus sein.Only one thread can be in upgradeable mode at any time. Eine beliebige Anzahl von Threads kann im Lesemodus befindet, und kann es möglicherweise ein Thread im erweiterbaren Modus befindet, während andere Threads befinden sich im Lesemodus.Any number of threads can be in read mode, and there can be one thread in upgradeable mode while other threads are in read mode.

Wichtig

Dieser Typ implementiert die IDisposable-Schnittstelle.This type implements the IDisposable interface. Nach Abschluss der Verwendung sollten Sie den Typ entweder direkt oder indirekt löschen.When you have finished using the type, you should dispose of it either directly or indirectly. Zum direkten Löschen des Typs rufen Sie seine Dispose-Methode in einem try/catch-Block auf.To dispose of the type directly, call its Dispose method in a try/catch block. Zum indirekten Löschen verwenden Sie ein Sprachkonstrukt wie using (in C#) oder Using (in Visual Basic).To dispose of it indirectly, use a language construct such as using (in C#) or Using (in Visual Basic). Weitere Informationen finden Sie im Abschnitt „Verwenden eines Objekts, das IDisposable implementiert“ des Themas „Die IDisposable-Schnittstelle“.For more information, see the "Using an Object that Implements IDisposable" section in the IDisposable interface topic.

ReaderWriterLockSlim Thread-Affinität ist verwaltet werden. Das heißt, jedes Thread Objekt muss eine eigene Methodenaufrufen zu aktivieren und Deaktivieren des Sperrmodi zu machen.ReaderWriterLockSlim has managed thread affinity; that is, each Thread object must make its own method calls to enter and exit lock modes. Kein Thread kann es sich um den Modus eines anderen Threads ändern.No thread can change the mode of another thread.

Wenn eine ReaderWriterLockSlim lässt keine Rekursion, einen Thread, versucht, die Sperre, verschiedene Ursachen haben blockieren können:If a ReaderWriterLockSlim does not allow recursion, a thread that tries to enter the lock can block for several reasons:

  • Ein Thread, der versucht, die im Lesemodus Blöcke eingeben, wenn andere Threads darauf warten, geben im Schreibmodus oder ein einzelnen Thread im Schreibmodus.A thread that tries to enter read mode blocks if there are threads waiting to enter write mode or if there is a single thread in write mode.

    Hinweis

    Neue Leser blockieren, wenn der Writer, in der Warteschlange befinden, ist eine Richtlinie der Sperre-Ausgewogenheit, die Schreiber bevorzugt.Blocking new readers when writers are queued is a lock fairness policy that favors writers. Die aktuelle Richtlinie für die Ausgewogenheit Salden Ausgewogenheit Lesern und Schreibern stammen, die zur Förderung der Durchsatz in den meisten häufigen Szenarien.The current fairness policy balances fairness to readers and writers, to promote throughput in the most common scenarios. Zukünftige Versionen von der .NET Framework.NET Framework kann neue Ausgewogenheit Richtlinien darstellen.Future versions of the .NET Framework.NET Framework may introduce new fairness policies.

  • Ein Thread, der versucht, die im erweiterbaren Modus Blöcke zu geben, wenn es ist bereits ein Thread im erweiterbaren Modus befindet, wenn es Threads Schreibmodus warten, oder es gibt ein einzelnen Thread im Schreibmodus.A thread that tries to enter upgradeable mode blocks if there is already a thread in upgradeable mode, if there are threads waiting to enter write mode, or if there is a single thread in write mode.

  • Ein Thread, der versucht, Schreibmodus blockiert, wenn ein Thread in jedem der drei Modi vorhanden ist.A thread that tries to enter write mode blocks if there is a thread in any of the three modes.

Upgrades und Downgrades SperrenUpgrading and Downgrading Locks

Zuweisung des erweiterbaren Modus ist für Fälle vorgesehen, in denen ein Thread in der Regel aus der geschützten Ressource liest, aber möglicherweise zu schreiben, wenn eine Bedingung erfüllt ist.Upgradeable mode is intended for cases where a thread usually reads from the protected resource, but might need to write to it if some condition is met. Ein Thread, hat eine ReaderWriterLockSlim im erweiterbaren Modus befindet, verfügt über Lesezugriff auf die geschützte Ressource und kann zum Schreiben von Modus durch Aufrufen der EnterWriteLock oder TryEnterWriteLock Methoden.A thread that has entered a ReaderWriterLockSlim in upgradeable mode has read access to the protected resource, and can upgrade to write mode by calling the EnterWriteLock or TryEnterWriteLock methods. Da vorhanden nur ein Thread im erweiterbaren Modus zu einem Zeitpunkt sein können, kann nicht den Schreibmodus Upgrade zu einem deadlock bei Rekursion nicht zulässig ist, ist die Standardrichtlinie.Because there can be only one thread in upgradeable mode at a time, upgrading to write mode cannot deadlock when recursion is not allowed, which is the default policy.

Wichtig

Unabhängig von die Rekursionsrichtlinie für die lesen ein Thread, der ursprünglich eingegebenen Modus darf nicht im erweiterbaren Modus oder im Schreibmodus befindet, aktualisieren, da dieses Muster eine hohe Wahrscheinlichkeit für Deadlocks erstellt.Regardless of recursion policy, a thread that initially entered read mode is not allowed to upgrade to upgradeable mode or write mode, because that pattern creates a strong probability of deadlocks. Z. B. wenn zwei Threads im Lesemodus befindet, die beide geben dann den Schreibmodus, sie in einem deadlock.For example, if two threads in read mode both try to enter write mode, they will deadlock. Zuweisung des erweiterbaren Modus soll diese Deadlocks zu vermeiden.Upgradeable mode is designed to avoid such deadlocks.

Wenn es andere Threads im Lesemodus, den Thread, der Blöcke aktualisiert wird.If there are other threads in read mode, the thread that is upgrading blocks. Während der Thread blockiert ist, werden die anderen Threads, die versuchen, den Lesemodus blockiert.While the thread is blocked, other threads that try to enter read mode are blocked. Wenn alle Threads den Lesemodus beendet haben, gibt der erweiterbaren blockierte Thread im Schreibmodus.When all threads have exited from read mode, the blocked upgradeable thread enters write mode. Wenn vorhanden, dass andere Threads darauf warten sind, geben den Schreibmodus, bleiben diese blockiert, da der einzelne Thread im erweiterbaren Modus befindet, die sie erhalten exklusiven Zugriff auf die Ressource verhindert.If there are other threads waiting to enter write mode, they remain blocked, because the single thread that is in upgradeable mode prevents them from gaining exclusive access to the resource.

Wenn der Thread im erweiterbaren Modus Schreibmodus beendet wird, können andere Threads, die darauf warten, Lesemodus hierzu Threads darauf warten, geben den Schreibmodus, es sei denn, es gibt.When the thread in upgradeable mode exits write mode, other threads that are waiting to enter read mode can do so, unless there are threads waiting to enter write mode. Der Thread im erweiterbaren Modus kann ein upgrade und downgrade auf unbestimmte Zeit, solange er der einzige Thread ist, der auf die geschützte Ressource schreibt.The thread in upgradeable mode can upgrade and downgrade indefinitely, as long as it is the only thread that writes to the protected resource.

Wichtig

Wenn Sie zulassen, dass mehrere Threads eingeben schreiben Sie oder den erweiterbaren Modus, Sie nicht auf einem Thread im erweiterbaren Modus Monopol auf zulassen müssen.If you allow multiple threads to enter write mode or upgradeable mode, you must not allow one thread to monopolize upgradeable mode. Schreiben Threads, die versuchen, geben andernfalls Modus direkt werden werden auf unbestimmte Zeit blockiert, und während sie blockiert werden, andere Threads nicht Lesemodus.Otherwise, threads that try to enter write mode directly will be blocked indefinitely, and while they are blocked, other threads will be unable to enter read mode.

Ein Thread im erweiterbaren Modus kann downgrade auf einen schreibgeschützten Modus durch den ersten Aufruf der EnterReadLock -Methode und dem anschließenden Aufrufen der ExitUpgradeableReadLock Methode.A thread in upgradeable mode can downgrade to read mode by first calling the EnterReadLock method and then calling the ExitUpgradeableReadLock method. Dieses Muster kann für alle Richtlinien, Sperren Rekursion, sogar NoRecursion.This downgrade pattern is allowed for all lock recursion policies, even NoRecursion.

Nach einem Downgrade Lesemodus kann kein Thread im erweiterbaren Modus geben Sie bis dieser den Lesemodus beendet wurde.After downgrading to read mode, a thread cannot reenter upgradeable mode until it has exited from read mode.

Die Sperre rekursiv eingebenEntering the Lock Recursively

Sie erstellen eine ReaderWriterLockSlim , die rekursive Sperren unterstützt mithilfe der ReaderWriterLockSlim(LockRecursionPolicy) Konstruktor, der angibt, für die Sperre, und geben LockRecursionPolicy.SupportsRecursion.You can create a ReaderWriterLockSlim that supports recursive lock entry by using the ReaderWriterLockSlim(LockRecursionPolicy) constructor that specifies lock policy, and specifying LockRecursionPolicy.SupportsRecursion.

Hinweis

Die Verwendung der Rekursion wird für neue Entwicklungen nicht empfohlen, da es unnötige Komplikationen eingeführt und wird Ihr Code anfälliger für Deadlocks.The use of recursion is not recommended for new development, because it introduces unnecessary complications and makes your code more prone to deadlocks.

Für eine ReaderWriterLockSlim , mit der Rekursion, die Folgendes gilt für die Modi kann ein Thread eingeben:For a ReaderWriterLockSlim that allows recursion, the following can be said about the modes a thread can enter:

  • Ein Thread im Lesemodus kann rekursiv, jedoch kann nicht im Schreibmodus oder im erweiterbaren Modus eingeben.A thread in read mode can enter read mode recursively, but cannot enter write mode or upgradeable mode. Wenn versucht wird, dazu einen LockRecursionException ausgelöst.If it tries to do this, a LockRecursionException is thrown. Eingabe gelesen, Modus und die anschließende Eingabe im Schreibmodus oder im erweiterbaren Modus ist ein Muster mit einer starken Wahrscheinlichkeit von Deadlocks, ist es nicht zulässig.Entering read mode and then entering write mode or upgradeable mode is a pattern with a strong probability of deadlocks, so it is not allowed. Wie bereits erwähnt, wird im erweiterbaren Modus für Fälle bereitgestellt, in denen eine Sperre ein upgrade erforderlich ist.As discussed earlier, upgradeable mode is provided for cases where it is necessary to upgrade a lock.

  • Ein Thread im erweiterbaren Modus Schreibmodus und/oder Lesemodus eingeben kann, und Sie können eines der drei Modi rekursiv eingeben.A thread in upgradeable mode can enter write mode and/or read mode, and can enter any of the three modes recursively. Allerdings ein Versuch, Schreibmodus blockiert, wenn andere Threads im Lesemodus ausgeführt werden.However, an attempt to enter write mode blocks if there are other threads in read mode.

  • Ein Thread im Schreibmodus kann geben, Lesemodus und/oder im erweiterbaren Modus befindet, und Sie können eines der drei Modi rekursiv eingeben.A thread in write mode can enter read mode and/or upgradeable mode, and can enter any of the three modes recursively.

  • Ein Thread, der nicht die Sperre zugewiesen ist, kann einem beliebigen Modus eingeben.A thread that has not entered the lock can enter any mode. Dieser Versuch kann aus denselben Gründen als Versuch, eine nicht rekursive Sperre blockiert.This attempt can block for the same reasons as an attempt to enter a non-recursive lock.

Ein Thread kann der Modi, in denen, die es in beliebiger Reihenfolge eingegeben hat, beenden, solange jeder Modus genau so häufig bei der Eingabe dieser Modus beenden.A thread can exit the modes it has entered in any order, as long as it exits each mode exactly as many times as it entered that mode. Wenn ein Thread versucht, einen Modus zu oft zu beenden, oder um einen Modus zu beenden, es nicht eingegeben werden wurde, eine SynchronizationLockException ausgelöst.If a thread tries to exit a mode too many times, or to exit a mode it has not entered, a SynchronizationLockException is thrown.

Status der SperreLock States

Möglicherweise finden Sie es nützlich, um die Sperre bezüglich ihrer Status vorstellen.You may find it useful to think of the lock in terms of its states. Ein ReaderWriterLockSlim einen von vier Status: nicht zugewiesen werden, lesen, aktualisieren und zu schreiben.A ReaderWriterLockSlim can be in one of four states: not entered, read, upgrade, and write.

  • Nicht eingegeben wird: In diesem Status keine Threads die Sperre eingegeben haben (oder alle Threads, die Sperre beendet haben).Not entered: In this state, no threads have entered the lock (or all threads have exited the lock).

  • Lesen: In diesem Zustand haben einen oder mehrere Threads die Sperre für den Lesezugriff auf die geschützte Ressource eingegeben.Read: In this state, one or more threads have entered the lock for read access to the protected resource.

    Hinweis

    Ein Thread kann die Sperre im Lesemodus Lesemodus, mithilfe der EnterReadLock oder TryEnterReadLock Methoden oder ein Downgrade von erweiterbaren Modus erhalten hat.A thread can enter the lock in read mode by using the EnterReadLock or TryEnterReadLock methods, or by downgrading from upgradeable mode.

  • Upgrade: In diesem Fall wurde ein Thread die Sperre für Lesezugriff mit der Option zum Aktualisieren, um Schreibzugriff eingegeben (d. h. im erweiterbaren Modus), und NULL oder mehr Threads die Sperre für den Lesezugriff eingegeben haben.Upgrade: In this state, one thread has entered the lock for read access with the option to upgrade to write access (that is, in upgradeable mode), and zero or more threads have entered the lock for read access. Nicht mehr als einem Thread zu einem Zeitpunkt kann die Sperre mit der Option zum Aktualisieren; Es werden zusätzliche Threads, die versuchen, die Zuweisung des erweiterbaren Modus blockiert.No more than one thread at a time can enter the lock with the option to upgrade; additional threads that try to enter upgradeable mode are blocked.

  • Schreiben: In diesem Fall wurde ein Thread die Sperre für den Schreibzugriff auf die geschützte Ressource zugewiesen.Write: In this state, one thread has entered the lock for write access to the protected resource. Dieser Thread befindet sich exklusiven Besitz der Sperre.That thread has exclusive possession of the lock. Es wird keinem anderen Thread, der versucht, die Sperre aus irgendeinem Grund blockiert.Any other thread that tries to enter the lock for any reason is blocked.

Die folgende Tabelle beschreibt die Übergänge zwischen Zuständen der Sperre, sperren, die keine Rekursion, wenn ein Thread zulassen t führt die Aktion, die in der linken Spalte beschrieben.The following table describes the transitions between lock states, for locks that do not allow recursion, when a thread t takes the action described in the leftmost column. Zum Zeitpunkt die Aktion dauert t Modus "keine" hat.At the time it takes the action, t has no mode. (Besonderen Fall, in denen t befindet sich im erweiterbaren Modus wird in die Fußnoten zur Tabelle beschrieben.) Die oberste Zeile gibt den ursprünglichen Status der Sperre.(The special case where t is in upgradeable mode is described in the table footnotes.) The top row describes the starting state of the lock. Die Zellen beschreiben, was geschieht mit den Thread, und Änderungen an den Sperrzustand in Klammern angezeigt.The cells describe what happens to the thread, and show changes to the lock state in parentheses.

Nicht zugewiesen (N)Not entered (N) Read (R)Read (R) Upgrade (U)Upgrade (U) Write (W)Write (W)
t fordert den Lesemodust enters read mode t Gibt ein (R).t enters (R). t blockiert, wenn Threads für den Schreibmodus warten; andernfalls t eingibt.t blocks if threads are waiting for write mode; otherwise, t enters. t blockiert, wenn Threads für den Schreibmodus warten; andernfalls t eingibt. 1t blocks if threads are waiting for write mode; otherwise, t enters.1 t blockiert.t blocks.
t fordert den erweiterbaren Modust enters upgradeable mode t Gibt ein (U).t enters (U). t blockiert, wenn Threads warten schreiben oder den erweiterbaren Modus; andernfalls t eingibt (U).t blocks if threads are waiting for write mode or upgrade mode; otherwise, t enters (U). t blockiert.t blocks. t blockiert.t blocks.
t wird der Schreibmodust enters write mode t Gibt (W).t enters (W). t blockiert.t blocks. t blockiert. 2t blocks.2 t blockiert.t blocks.

1 Wenn t startet, gibt es im erweiterbaren Modus befindet, im Lesemodus.1 If t starts out in upgradeable mode, it enters read mode. Diese Aktion wird nie blockiert.This action never blocks. Der Zustand der Sperre wird nicht geändert werden.The lock state does not change. (Der Thread kann dann eine Herabstufung Lesemodus beim Verlassen des erweiterbaren Modus durchführen.)(The thread can then complete a downgrade to read mode by exiting upgradeable mode.)

2 Wenn t beginnt im erweiterbaren Modus erhalten hat, er blockiert wird, wenn im Lesemodus Threads vorhanden sind.2 If t starts out in upgradeable mode, it blocks if there are threads in read mode. Andernfalls wird es den Schreibmodus aktualisiert.Otherwise it upgrades to write mode. Der Zustand der remotesperre ändert Write (W).The lock state changes to Write (W). Wenn t blockiert, da Threads vorhanden, im Lesemodus sind wird der Schreibmodus, sobald der letzte Thread im Lesemodus beendet wird, auch wenn Threads darauf warten, geben im Schreibmodus.If t blocks because there are threads in read mode, it enters write mode as soon as the last thread exits read mode, even if there are threads waiting to enter write mode.

Tritt eine statusänderung, da ein Thread die Sperre wieder freigibt, wird der nächste Thread, der aktiviert werden wie folgt ausgewählt:When a state change occurs because a thread exits the lock, the next thread to be awakened is selected as follows:

  • Zunächst wird ein Thread, der wartet, wird im Schreibmodus, und ist bereits im erweiterbaren Modus befindet (es kann sein darf höchstens ein solcher Thread).First, a thread that is waiting for write mode and is already in upgradeable mode (there can be at most one such thread).

  • Andernfalls ein Thread, der für den Schreibmodus wartet.Failing that, a thread that is waiting for write mode.

  • Andernfalls ein Thread, der für den erweiterbaren Modus warten ist.Failing that, a thread that is waiting for upgradeable mode.

  • Falls dies fehlschlägt, alle Threads, die für den Lesemodus warten.Failing that, all threads that are waiting for read mode.

Die nachfolgende Stand der Sperre ist immer Write (W) in der ersten beiden Fälle und Upgrade (U) in den dritten Fall, unabhängig vom Status der Sperre, wenn der vorhandene Thread die statusänderung ausgelöst.The subsequent state of the lock is always Write (W) in the first two cases and Upgrade (U) in the third case, regardless of the state of the lock when the exiting thread triggered the state change. Im letzten Fall ist der Status der Sperre aktualisieren (U), wenn es ein Thread im erweiterbaren Modus nach der Änderung und Read (R), andernfalls unabhängig von den vorherigen Zustand.In the last case, the state of the lock is Upgrade (U) if there is a thread in upgradeable mode after the state change, and Read (R) otherwise, regardless of the prior state.

Konstruktoren

ReaderWriterLockSlim() ReaderWriterLockSlim() ReaderWriterLockSlim() ReaderWriterLockSlim()

Initialisiert eine neue Instanz der ReaderWriterLockSlim-Klasse mit Standardeigenschaftswerten.Initializes a new instance of the ReaderWriterLockSlim class with default property values.

ReaderWriterLockSlim(LockRecursionPolicy) ReaderWriterLockSlim(LockRecursionPolicy) ReaderWriterLockSlim(LockRecursionPolicy) ReaderWriterLockSlim(LockRecursionPolicy)

Initialisiert eine neue Instanz der ReaderWriterLockSlim-Klasse unter Angabe der Rekursionsrichtlinie für die Sperre.Initializes a new instance of the ReaderWriterLockSlim class, specifying the lock recursion policy.

Eigenschaften

CurrentReadCount CurrentReadCount CurrentReadCount CurrentReadCount

Ruft die Gesamtzahl von eindeutigen Threads ab, denen die Sperre im Lesemodus zugewiesen ist.Gets the total number of unique threads that have entered the lock in read mode.

IsReadLockHeld IsReadLockHeld IsReadLockHeld IsReadLockHeld

Ruft einen Wert ab, der angibt, ob die Sperre dem aktuellen Thread im Lesemodus zugewiesen ist.Gets a value that indicates whether the current thread has entered the lock in read mode.

IsUpgradeableReadLockHeld IsUpgradeableReadLockHeld IsUpgradeableReadLockHeld IsUpgradeableReadLockHeld

Ruft einen Wert ab, der angibt, ob die Sperre dem aktuellen Thread im erweiterbaren Modus zugewiesen ist.Gets a value that indicates whether the current thread has entered the lock in upgradeable mode.

IsWriteLockHeld IsWriteLockHeld IsWriteLockHeld IsWriteLockHeld

Ruft einen Wert ab, der angibt, ob die Sperre dem aktuellen Thread im Schreibmodus zugewiesen ist.Gets a value that indicates whether the current thread has entered the lock in write mode.

RecursionPolicy RecursionPolicy RecursionPolicy RecursionPolicy

Ruft einen Wert ab, der die Rekursionsrichtlinie für das aktuelle ReaderWriterLockSlim-Objekt angibt.Gets a value that indicates the recursion policy for the current ReaderWriterLockSlim object.

RecursiveReadCount RecursiveReadCount RecursiveReadCount RecursiveReadCount

Ruft einen Wert ab, der als Indikator für eine Rekursion angibt, wie oft dem aktuellen Thread die Sperre im Lesemodus zugewiesen ist.Gets the number of times the current thread has entered the lock in read mode, as an indication of recursion.

RecursiveUpgradeCount RecursiveUpgradeCount RecursiveUpgradeCount RecursiveUpgradeCount

Ruft einen Wert ab, der als Indikator für eine Rekursion angibt, wie oft dem aktuellen Thread die Sperre im erweiterbaren Modus zugewiesen ist.Gets the number of times the current thread has entered the lock in upgradeable mode, as an indication of recursion.

RecursiveWriteCount RecursiveWriteCount RecursiveWriteCount RecursiveWriteCount

Ruft einen Wert ab, der als Indikator für eine Rekursion angibt, wie oft dem aktuellen Thread die Sperre im Schreibmodus zugewiesen ist.Gets the number of times the current thread has entered the lock in write mode, as an indication of recursion.

WaitingReadCount WaitingReadCount WaitingReadCount WaitingReadCount

Ruft die Gesamtzahl von Threads ab, die auf eine Zuweisung der Sperre im Lesemodus warten.Gets the total number of threads that are waiting to enter the lock in read mode.

WaitingUpgradeCount WaitingUpgradeCount WaitingUpgradeCount WaitingUpgradeCount

Ruft die Gesamtzahl von Threads ab, die auf eine Zuweisung der Sperre im erweiterbaren Modus warten.Gets the total number of threads that are waiting to enter the lock in upgradeable mode.

WaitingWriteCount WaitingWriteCount WaitingWriteCount WaitingWriteCount

Ruft die Gesamtzahl von Threads ab, die auf eine Zuweisung der Sperre im Schreibmodus warten.Gets the total number of threads that are waiting to enter the lock in write mode.

Methoden

Dispose() Dispose() Dispose() Dispose()

Gibt alle von der aktuellen Instanz der ReaderWriterLockSlim-Klasse verwendeten Ressourcen frei.Releases all resources used by the current instance of the ReaderWriterLockSlim class.

EnterReadLock() EnterReadLock() EnterReadLock() EnterReadLock()

Versucht, die Sperre im Lesemodus zu erhalten.Tries to enter the lock in read mode.

EnterUpgradeableReadLock() EnterUpgradeableReadLock() EnterUpgradeableReadLock() EnterUpgradeableReadLock()

Versucht, die Sperre im erweiterbaren Modus zu erhalten.Tries to enter the lock in upgradeable mode.

EnterWriteLock() EnterWriteLock() EnterWriteLock() EnterWriteLock()

Versucht, die Sperre im Schreibmodus zu erhalten.Tries to enter the lock in write mode.

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

Bestimmt, ob das angegebene Objekt mit dem aktuellen Objekt identisch ist.Determines whether the specified object is equal to the current object.

(Inherited from Object)
ExitReadLock() ExitReadLock() ExitReadLock() ExitReadLock()

Verringert die Rekursionszahl für den Lesemodus und beendet den Lesemodus, wenn das Rekursionsergebnis 0 (null) ist.Reduces the recursion count for read mode, and exits read mode if the resulting count is 0 (zero).

ExitUpgradeableReadLock() ExitUpgradeableReadLock() ExitUpgradeableReadLock() ExitUpgradeableReadLock()

Verringert die Rekursionszahl für den erweiterbaren Modus und beendet den erweiterbaren Modus, wenn das Rekursionsergebnis 0 (null) ist.Reduces the recursion count for upgradeable mode, and exits upgradeable mode if the resulting count is 0 (zero).

ExitWriteLock() ExitWriteLock() ExitWriteLock() ExitWriteLock()

Verringert die Rekursionszahl für den Schreibmodus und beendet den Schreibmodus, wenn das Rekursionsergebnis 0 (null) ist.Reduces the recursion count for write mode, and exits write mode if the resulting count is 0 (zero).

GetHashCode() GetHashCode() GetHashCode() GetHashCode()

Fungiert als Standardhashfunktion.Serves as the default hash function.

(Inherited from Object)
GetType() GetType() GetType() GetType()

Ruft den Type der aktuellen Instanz ab.Gets the Type of the current instance.

(Inherited from Object)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

Erstellt eine flache Kopie des aktuellen Object.Creates a shallow copy of the current Object.

(Inherited from Object)
ToString() ToString() ToString() ToString()

Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt.Returns a string that represents the current object.

(Inherited from Object)
TryEnterReadLock(Int32) TryEnterReadLock(Int32) TryEnterReadLock(Int32) TryEnterReadLock(Int32)

Versucht, die Sperre im Lesemodus zu erhalten. Optional wird ein ganzzahliger Timeout berücksichtigt.Tries to enter the lock in read mode, with an optional integer time-out.

TryEnterReadLock(TimeSpan) TryEnterReadLock(TimeSpan) TryEnterReadLock(TimeSpan) TryEnterReadLock(TimeSpan)

Versucht, die Sperre im Lesemodus zu erhalten. Optional wird ein Timeout berücksichtigt.Tries to enter the lock in read mode, with an optional time-out.

TryEnterUpgradeableReadLock(Int32) TryEnterUpgradeableReadLock(Int32) TryEnterUpgradeableReadLock(Int32) TryEnterUpgradeableReadLock(Int32)

Versucht, die Sperre im erweiterbaren Modus zu erhalten. Optional wird ein Timeout berücksichtigt.Tries to enter the lock in upgradeable mode, with an optional time-out.

TryEnterUpgradeableReadLock(TimeSpan) TryEnterUpgradeableReadLock(TimeSpan) TryEnterUpgradeableReadLock(TimeSpan) TryEnterUpgradeableReadLock(TimeSpan)

Versucht, die Sperre im erweiterbaren Modus zu erhalten. Optional wird ein Timeout berücksichtigt.Tries to enter the lock in upgradeable mode, with an optional time-out.

TryEnterWriteLock(Int32) TryEnterWriteLock(Int32) TryEnterWriteLock(Int32) TryEnterWriteLock(Int32)

Versucht, die Sperre im Schreibmodus zu erhalten. Optional wird ein Timeout berücksichtigt.Tries to enter the lock in write mode, with an optional time-out.

TryEnterWriteLock(TimeSpan) TryEnterWriteLock(TimeSpan) TryEnterWriteLock(TimeSpan) TryEnterWriteLock(TimeSpan)

Versucht, die Sperre im Schreibmodus zu erhalten. Optional wird ein Timeout berücksichtigt.Tries to enter the lock in write mode, with an optional time-out.

Gilt für:

Threadsicherheit

Dieser Typ ist threadsicher.This type is thread safe.