ReaderWriterLock ReaderWriterLock ReaderWriterLock ReaderWriterLock Class

Définition

Définit un verrou qui prend en charge les writers uniques et les lecteurs multiples.Defines a lock that supports single writers and multiple readers.

public ref class ReaderWriterLock sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
type ReaderWriterLock = class
    inherit CriticalFinalizerObject
Public NotInheritable Class ReaderWriterLock
Inherits CriticalFinalizerObject
Héritage
ReaderWriterLockReaderWriterLockReaderWriterLockReaderWriterLock
Attributs

Exemples

L’exemple suivant montre comment utiliser un ReaderWriterLock pour protéger une ressource partagée, une valeur entière nommée resource, qui est lue simultanément et écrite exclusivement par plusieurs threads.The following example demonstrates how to use a ReaderWriterLock to protect a shared resource, an integer value named resource, that is read concurrently and written exclusively by multiple threads. Notez que ReaderWriterLock est déclaré au niveau de la classe afin qu’il soit visible pour tous les threads.Note that the ReaderWriterLock is declared at the class level so that it is visible to all threads.

// This example shows a ReaderWriterLock protecting a shared
// resource that is read concurrently and written exclusively
// by multiple threads.
// The complete code is located in the ReaderWriterLock
// class topic.
using namespace System;
using namespace System::Threading;
public ref class Test
{
public:

   // Declaring the ReaderWriterLock at the class level
   // makes it visible to all threads.
   static ReaderWriterLock^ rwl = gcnew ReaderWriterLock;

   // For this example, the shared resource protected by the
   // ReaderWriterLock is just an integer.
   static int resource = 0;

   literal int numThreads = 26;
   static bool running = true;
   static Random^ rnd = gcnew Random;

   // Statistics.
   static int readerTimeouts = 0;
   static int writerTimeouts = 0;
   static int reads = 0;
   static int writes = 0;
   static void ThreadProc()
   {
      
      // As long as a thread runs, it randomly selects
      // various ways to read and write from the shared 
      // resource. Each of the methods demonstrates one 
      // or more features of ReaderWriterLock.
      while ( running )
      {
         double action = rnd->NextDouble();
         if ( action < .8 )
                  ReadFromResource( 10 );
         else
         if ( action < .81 )
                  ReleaseRestore( 50 );
         else
         if ( action < .90 )
                  UpgradeDowngrade( 100 );
         else
                  WriteToResource( 100 );
      }
   }


   // Shows how to request and release a reader lock, and
   // how to handle time-outs.
   static void ReadFromResource( int timeOut )
   {
      try
      {
         rwl->AcquireReaderLock( timeOut );
         try
         {
            
            // It is safe for this thread to read from
            // the shared resource.
            Display( String::Format( "reads resource value {0}", resource ) );
            Interlocked::Increment( reads );
         }
         finally
         {
            
            // Ensure that the lock is released.
            rwl->ReleaseReaderLock();
         }

      }
      catch ( ApplicationException^ ) 
      {
         
         // The reader lock request timed out.
         Interlocked::Increment( readerTimeouts );
      }

   }


   // Shows how to request and release the writer lock, and
   // how to handle time-outs.
   static void WriteToResource( int timeOut )
   {
      try
      {
         rwl->AcquireWriterLock( timeOut );
         try
         {
            
            // It is safe for this thread to read or write
            // from the shared resource.
            resource = rnd->Next( 500 );
            Display( String::Format( "writes resource value {0}", resource ) );
            Interlocked::Increment( writes );
         }
         finally
         {
            
            // Ensure that the lock is released.
            rwl->ReleaseWriterLock();
         }

      }
      catch ( ApplicationException^ ) 
      {
         
         // The writer lock request timed out.
         Interlocked::Increment( writerTimeouts );
      }

   }


   // Shows how to request a reader lock, upgrade the
   // reader lock to the writer lock, and downgrade to a
   // reader lock again.
   static void UpgradeDowngrade( int timeOut )
   {
      try
      {
         rwl->AcquireReaderLock( timeOut );
         try
         {
            
            // It is safe for this thread to read from
            // the shared resource.
            Display( String::Format( "reads resource value {0}", resource ) );
            Interlocked::Increment( reads );
            
            // If it is necessary to write to the resource,
            // you must either release the reader lock and 
            // then request the writer lock, or upgrade the
            // reader lock. Note that upgrading the reader lock
            // puts the thread in the write queue, behind any
            // other threads that might be waiting for the 
            // writer lock.
            try
            {
               LockCookie lc = rwl->UpgradeToWriterLock( timeOut );
               try
               {
                  
                  // It is safe for this thread to read or write
                  // from the shared resource.
                  resource = rnd->Next( 500 );
                  Display( String::Format( "writes resource value {0}", resource ) );
                  Interlocked::Increment( writes );
               }
               finally
               {
                  
                  // Ensure that the lock is released.
                  rwl->DowngradeFromWriterLock( lc );
               }

            }
            catch ( ApplicationException^ ) 
            {
               
               // The upgrade request timed out.
               Interlocked::Increment( writerTimeouts );
            }

            
            // When the lock has been downgraded, it is 
            // still safe to read from the resource.
            Display( String::Format( "reads resource value {0}", resource ) );
            Interlocked::Increment( reads );
         }
         finally
         {
            
            // Ensure that the lock is released.
            rwl->ReleaseReaderLock();
         }

      }
      catch ( ApplicationException^ ) 
      {
         
         // The reader lock request timed out.
         Interlocked::Increment( readerTimeouts );
      }

   }


   // Shows how to release all locks and later restore
   // the lock state. Shows how to use sequence numbers
   // to determine whether another thread has obtained
   // a writer lock since this thread last accessed the
   // resource.
   static void ReleaseRestore( int timeOut )
   {
      int lastWriter;
      try
      {
         rwl->AcquireReaderLock( timeOut );
         try
         {
            
            // It is safe for this thread to read from
            // the shared resource. Cache the value. (You
            // might do this if reading the resource is
            // an expensive operation.)
            int resourceValue = resource;
            Display( String::Format( "reads resource value {0}", resourceValue ) );
            Interlocked::Increment( reads );
            
            // Save the current writer sequence number.
            lastWriter = rwl->WriterSeqNum;
            
            // Release the lock, and save a cookie so the
            // lock can be restored later.
            LockCookie lc = rwl->ReleaseLock();
            
            // Wait for a random interval (up to a 
            // quarter of a second), and then restore
            // the previous state of the lock. Note that
            // there is no timeout on the Restore method.
            Thread::Sleep( rnd->Next( 250 ) );
            rwl->RestoreLock( lc );
            
            // Check whether other threads obtained the
            // writer lock in the interval. If not, then
            // the cached value of the resource is still
            // valid.
            if ( rwl->AnyWritersSince( lastWriter ) )
            {
               resourceValue = resource;
               Interlocked::Increment( reads );
               Display( String::Format( "resource has changed {0}", resourceValue ) );
            }
            else
            {
               Display( String::Format( "resource has not changed {0}", resourceValue ) );
            }
         }
         finally
         {
            
            // Ensure that the lock is released.
            rwl->ReleaseReaderLock();
         }

      }
      catch ( ApplicationException^ ) 
      {
         
         // The reader lock request timed out.
         Interlocked::Increment( readerTimeouts );
      }

   }


   // Helper method briefly displays the most recent
   // thread action. Comment out calls to Display to 
   // get a better idea of throughput.
   static void Display( String^ msg )
   {
      Console::Write( "Thread {0} {1}.       \r", Thread::CurrentThread->Name, msg );
   }

};


int main()
{
   array<String^>^args = Environment::GetCommandLineArgs();
   
   // Start a series of threads. Each thread randomly
   // performs reads and writes on the shared resource.
   array<Thread^>^t = gcnew array<Thread^>(Test::numThreads);
   for ( int i = 0; i < Test::numThreads; i++ )
   {
      t[ i ] = gcnew Thread( gcnew ThreadStart( Test::ThreadProc ) );
      t[ i ]->Name = gcnew String( Convert::ToChar( i + 65 ),1 );
      t[ i ]->Start();
      if ( i > 10 )
            Thread::Sleep( 300 );

   }
   
   // Tell the threads to shut down, then wait until they all
   // finish.
   Test::running = false;
   for ( int i = 0; i < Test::numThreads; i++ )
   {
      t[ i ]->Join();

   }
   
   // Display statistics.
   Console::WriteLine( "\r\n {0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.", Test::reads, Test::writes, Test::readerTimeouts, Test::writerTimeouts );
   Console::WriteLine( "Press ENTER to exit." );
   Console::ReadLine();
   return 0;
}

// The complete code is located in the ReaderWriterLock class topic.
using System;
using System.Threading;

public class Example
{
   static ReaderWriterLock rwl = new ReaderWriterLock();
   // Define the shared resource protected by the ReaderWriterLock.
   static int resource = 0;

   const int numThreads = 26;
   static bool running = true;
   static Random rnd = new Random();

   // Statistics.
   static int readerTimeouts = 0;
   static int writerTimeouts = 0;
   static int reads = 0;
   static int writes = 0;

   public static void Main()
   {
      // Start a series of threads to randomly read from and
      // write to the shared resource.
      Thread[] t = new Thread[numThreads];
      for (int i = 0; i < numThreads; i++){
         t[i] = new Thread(new ThreadStart(ThreadProc));
         t[i].Name = new String(Convert.ToChar(i + 65), 1);
         t[i].Start();
         if (i > 10)
            Thread.Sleep(300);
      }

      // Tell the threads to shut down and wait until they all finish.
      running = false;
      for (int i = 0; i < numThreads; i++)
         t[i].Join();

      // Display statistics.
      Console.WriteLine("\n{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
            reads, writes, readerTimeouts, writerTimeouts);
      Console.Write("Press ENTER to exit... ");
      Console.ReadLine();
   }

   static void ThreadProc()
   {
      // Randomly select a way for the thread to read and write from the shared
      // resource.
      while (running) {
         double action = rnd.NextDouble();
         if (action < .8)
            ReadFromResource(10);
         else if (action < .81)
            ReleaseRestore(50);
         else if (action < .90)
            UpgradeDowngrade(100);
         else
            WriteToResource(100);
      }
   }

   // Request and release a reader lock, and handle time-outs.
   static void ReadFromResource(int timeOut)
   {
      try {
         rwl.AcquireReaderLock(timeOut);
         try {
            // It is safe for this thread to read from the shared resource.
            Display("reads resource value " + resource);
            Interlocked.Increment(ref reads);
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseReaderLock();
         }
      }
      catch (ApplicationException) {
         // The reader lock request timed out.
         Interlocked.Increment(ref readerTimeouts);
      }
   }

   // Request and release the writer lock, and handle time-outs.
   static void WriteToResource(int timeOut)
   {
      try {
         rwl.AcquireWriterLock(timeOut);
         try {
            // It's safe for this thread to access from the shared resource.
            resource = rnd.Next(500);
            Display("writes resource value " + resource);
            Interlocked.Increment(ref writes);
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseWriterLock();
         }
      }
      catch (ApplicationException) {
         // The writer lock request timed out.
         Interlocked.Increment(ref writerTimeouts);
      }
   }

   // Requests a reader lock, upgrades the reader lock to the writer
   // lock, and downgrades it to a reader lock again.
   static void UpgradeDowngrade(int timeOut)
   {
      try {
         rwl.AcquireReaderLock(timeOut);
         try {
            // It's safe for this thread to read from the shared resource.
            Display("reads resource value " + resource);
            Interlocked.Increment(ref reads);

            // To write to the resource, either release the reader lock and
            // request the writer lock, or upgrade the reader lock. Upgrading
            // the reader lock puts the thread in the write queue, behind any
            // other threads that might be waiting for the writer lock.
            try {
               LockCookie lc = rwl.UpgradeToWriterLock(timeOut);
               try {
                  // It's safe for this thread to read or write from the shared resource.
                  resource = rnd.Next(500);
                  Display("writes resource value " + resource);
                  Interlocked.Increment(ref writes);
               }
               finally {
                  // Ensure that the lock is released.
                  rwl.DowngradeFromWriterLock(ref lc);
               }
            }
            catch (ApplicationException) {
               // The upgrade request timed out.
               Interlocked.Increment(ref writerTimeouts);
            }

            // If the lock was downgraded, it's still safe to read from the resource.
            Display("reads resource value " + resource);
            Interlocked.Increment(ref reads);
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseReaderLock();
         }
      }
      catch (ApplicationException) {
         // The reader lock request timed out.
         Interlocked.Increment(ref readerTimeouts);
      }
   }

   // Release all locks and later restores the lock state.
   // Uses sequence numbers to determine whether another thread has
   // obtained a writer lock since this thread last accessed the resource.
   static void ReleaseRestore(int timeOut)
   {
      int lastWriter;

      try {
         rwl.AcquireReaderLock(timeOut);
         try {
            // It's safe for this thread to read from the shared resource,
            // so read and cache the resource value.
            int resourceValue = resource;     // Cache the resource value.
            Display("reads resource value " + resourceValue);
            Interlocked.Increment(ref reads);

            // Save the current writer sequence number.
            lastWriter = rwl.WriterSeqNum;

            // Release the lock and save a cookie so the lock can be restored later.
            LockCookie lc = rwl.ReleaseLock();

            // Wait for a random interval and then restore the previous state of the lock.
            Thread.Sleep(rnd.Next(250));
            rwl.RestoreLock(ref lc);

            // Check whether other threads obtained the writer lock in the interval.
            // If not, then the cached value of the resource is still valid.
            if (rwl.AnyWritersSince(lastWriter)) {
               resourceValue = resource;
               Interlocked.Increment(ref reads);
               Display("resource has changed " + resourceValue);
            }
            else {
               Display("resource has not changed " + resourceValue);
            }
         }
         finally {
            // Ensure that the lock is released.
            rwl.ReleaseReaderLock();
         }
      }
      catch (ApplicationException) {
         // The reader lock request timed out.
         Interlocked.Increment(ref readerTimeouts);
      }
   }

   // Helper method briefly displays the most recent thread action.
   static void Display(string msg)
   {
      Console.Write("Thread {0} {1}.       \r", Thread.CurrentThread.Name, msg);
   }
}
' The complete code is located in the ReaderWriterLock class topic.
Imports System.Threading

Public Module Example
   Private rwl As New ReaderWriterLock()
   ' Define the shared resource protected by the ReaderWriterLock.
   Private resource As Integer = 0

   Const numThreads As Integer = 26
   Private running As Boolean = True
   Private rnd As New Random()
   
   ' Statistics.
   Private readerTimeouts As Integer = 0
   Private writerTimeouts As Integer = 0
   Private reads As Integer = 0
   Private writes As Integer = 0
  
   Public Sub Main()
      ' Start a series of threads to randomly read from and
      ' write to the shared resource.
      Dim t(numThreads - 1) As Thread
      Dim i As Integer
      For i = 0 To numThreads - 1
         t(i) = New Thread(New ThreadStart(AddressOf ThreadProc))
         t(i).Name = Chr(i + 65)
         t(i).Start()
         If i > 10 Then
            Thread.Sleep(300)
         End If
      Next

      ' Tell the threads to shut down and wait until they all finish.
      running = False
      For i = 0 To numThreads - 1
         t(i).Join()
      Next
      
      ' Display statistics.
      Console.WriteLine(vbCrLf & "{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
                        reads, writes, readerTimeouts, writerTimeouts)
      Console.Write("Press ENTER to exit... ")
      Console.ReadLine()
   End Sub

   Sub ThreadProc()
      ' Randomly select a way for the thread to read and write from the shared
      ' resource.
      While running
         Dim action As Double = rnd.NextDouble()
         If action < 0.8 Then
            ReadFromResource(10)
         ElseIf action < 0.81 Then
            ReleaseRestore(50)
         ElseIf action < 0.9 Then
            UpgradeDowngrade(100)
         Else
            WriteToResource(100)
         End If
      End While
   End Sub
    
   ' Request and release a reader lock, and handle time-outs.
   Sub ReadFromResource(timeOut As Integer)
      Try
         rwl.AcquireReaderLock(timeOut)
         Try
            ' It's safe for this thread to read from the shared resource.
            Display("reads resource value " & resource)
            Interlocked.Increment(reads)
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseReaderLock()
         End Try
      Catch ex As ApplicationException
         ' The reader lock request timed out.
         Interlocked.Increment(readerTimeouts)
      End Try
   End Sub

   ' Request and release the writer lock, and handle time-outs.
   Sub WriteToResource(timeOut As Integer)
      Try
         rwl.AcquireWriterLock(timeOut)
         Try
            ' It's safe for this thread to read or write from the shared resource.
            resource = rnd.Next(500)
            Display("writes resource value " & resource)
            Interlocked.Increment(writes)
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseWriterLock()
         End Try
      Catch ex As ApplicationException
         ' The writer lock request timed out.
         Interlocked.Increment(writerTimeouts)
      End Try
   End Sub

   ' Requests a reader lock, upgrades the reader lock to the writer
   ' lock, and downgrades it to a reader lock again.
   Sub UpgradeDowngrade(timeOut As Integer)
      Try
         rwl.AcquireReaderLock(timeOut)
         Try
            ' It's safe for this thread to read from the shared resource.
            Display("reads resource value " & resource)
            Interlocked.Increment(reads)
            
            ' To write to the resource, either release the reader lock and
            ' request the writer lock, or upgrade the reader lock. Upgrading
            ' the reader lock puts the thread in the write queue, behind any
            ' other threads that might be waiting for the writer lock.
            Try
               Dim lc As LockCookie = rwl.UpgradeToWriterLock(timeOut)
               Try
                  ' It's safe for this thread to read or write from the shared resource.
                  resource = rnd.Next(500)
                  Display("writes resource value " & resource)
                  Interlocked.Increment(writes)
               Finally
                  ' Ensure that the lock is released.
                  rwl.DowngradeFromWriterLock(lc)
               End Try
            Catch ex As ApplicationException
               ' The upgrade request timed out.
               Interlocked.Increment(writerTimeouts)
            End Try
            
            ' If the lock was downgraded, it's still safe to read from the resource.
            Display("reads resource value " & resource)
            Interlocked.Increment(reads)
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseReaderLock()
         End Try
      Catch ex As ApplicationException
         ' The reader lock request timed out.
         Interlocked.Increment(readerTimeouts)
      End Try
   End Sub

   ' Release all locks and later restores the lock state.
   ' Uses sequence numbers to determine whether another thread has
   ' obtained a writer lock since this thread last accessed the resource.
   Sub ReleaseRestore(timeOut As Integer)
      Dim lastWriter As Integer
      
      Try
         rwl.AcquireReaderLock(timeOut)
         Try
            ' It's safe for this thread to read from the shared resource,
            ' so read and cache the resource value.
            Dim resourceValue As Integer = resource
            Display("reads resource value " & resourceValue)
            Interlocked.Increment(reads)
            
            ' Save the current writer sequence number.
            lastWriter = rwl.WriterSeqNum
            
            ' Release the lock and save a cookie so the lock can be restored later.
            Dim lc As LockCookie = rwl.ReleaseLock()
            
            ' Wait for a random interval and then restore the previous state of the lock.
            Thread.Sleep(rnd.Next(250))
            rwl.RestoreLock(lc)
           
            ' Check whether other threads obtained the writer lock in the interval.
            ' If not, then the cached value of the resource is still valid.
            If rwl.AnyWritersSince(lastWriter) Then
               resourceValue = resource
               Interlocked.Increment(reads)
               Display("resource has changed " & resourceValue)
            Else
               Display("resource has not changed " & resourceValue)
            End If
         Finally
            ' Ensure that the lock is released.
            rwl.ReleaseReaderLock()
         End Try
      Catch ex As ApplicationException
         ' The reader lock request timed out.
         Interlocked.Increment(readerTimeouts)
      End Try
   End Sub

   ' Helper method briefly displays the most recent thread action.
   Sub Display(msg As String)
      Console.Write("Thread {0} {1}.       " & vbCr, Thread.CurrentThread.Name, msg)
   End Sub
End Module

Remarques

Important

Le .NET Framework.NET Framework a deux verrous de lecteur-writer, à savoir ReaderWriterLockSlim et ReaderWriterLock.The .NET Framework.NET Framework has two reader-writer locks, ReaderWriterLockSlim and ReaderWriterLock. ReaderWriterLockSlim est recommandé pour tout nouveau développement.ReaderWriterLockSlim is recommended for all new development. ReaderWriterLockSlim est similaire à ReaderWriterLock, mais a des règles simplifiées pour la récursivité ainsi que la mise à niveau et la rétrogradation de l’état de verrou.ReaderWriterLockSlim is similar to ReaderWriterLock, but it has simplified rules for recursion and for upgrading and downgrading lock state. ReaderWriterLockSlim évite de nombreux cas d’interblocage potentiel.ReaderWriterLockSlim avoids many cases of potential deadlock. En outre, les performances de ReaderWriterLockSlim sont considérablement meilleures que celles de ReaderWriterLock.In addition, the performance of ReaderWriterLockSlim is significantly better than ReaderWriterLock.

ReaderWriterLockest utilisé pour synchroniser l’accès à une ressource.ReaderWriterLock is used to synchronize access to a resource. À un moment donné, il autorise l’accès en lecture simultané pour plusieurs threads, ou l’accès en écriture pour un seul thread.At any given time, it allows either concurrent read access for multiple threads, or write access for a single thread. Dans le cas où une ressource est rarement modifiée, un offre ReaderWriterLock un meilleur débit qu’un simple verrou un à un, tel que. MonitorIn a situation where a resource is changed infrequently, a ReaderWriterLock provides better throughput than a simple one-at-a-time lock, such as Monitor.

ReaderWriterLockfonctionne mieux lorsque la plupart des accès sont des lectures, tandis que les écritures sont peu fréquentes et courtes.ReaderWriterLock works best where most accesses are reads, while writes are infrequent and of short duration. Plusieurs lecteurs alternent avec les enregistreurs uniques, afin que les lecteurs et les enregistreurs ne soient pas bloqués pendant de longues périodes.Multiple readers alternate with single writers, so that neither readers nor writers are blocked for long periods.

Notes

Le maintien des verrous de lecteur ou des verrous d’écriture pour de longues périodes prive les autres threads.Holding reader locks or writer locks for long periods will starve other threads. Pour des performances optimales, envisagez de restructurer votre application afin de réduire la durée des écritures.For best performance, consider restructuring your application to minimize the duration of writes.

Un thread peut contenir un verrou de lecteur ou un verrou de writer, mais pas les deux à la fois.A thread can hold a reader lock or a writer lock, but not both at the same time. Au lieu de libérer un verrou de lecteur pour acquérir le verrou de writer, vous pouvez UpgradeToWriterLock utiliser DowngradeFromWriterLocket.Instead of releasing a reader lock in order to acquire the writer lock, you can use UpgradeToWriterLock and DowngradeFromWriterLock.

Les requêtes de verrous récursives augmentent le nombre de verrous sur un verrou.Recursive lock requests increase the lock count on a lock.

Les lecteurs et les enregistreurs sont mis en file d’attente séparément.Readers and writers are queued separately. Quand un thread libère le verrou d’écriture, tous les threads en attente dans la file d’attente du lecteur reçoivent des verrous de lecteur. Lorsque tous ces verrous de lecteur ont été libérés, le thread suivant qui attend dans la file d’attente du writer, le cas échéant, reçoit le verrou de writer, et ainsi de suite.When a thread releases the writer lock, all threads waiting in the reader queue at that instant are granted reader locks; when all of those reader locks have been released, the next thread waiting in the writer queue, if any, is granted the writer lock, and so on. En d’autres termes ReaderWriterLock , alterne entre une collection de lecteurs et un writer.In other words, ReaderWriterLock alternates between a collection of readers, and one writer.

Alors qu’un thread dans la file d’attente du writer attend la libération de verrous de lecteur actifs, les threads qui demandent de nouveaux verrous de lecteur s’accumulent dans la file d’attente du lecteur.While a thread in the writer queue is waiting for active reader locks to be released, threads requesting new reader locks accumulate in the reader queue. Leurs demandes ne sont pas accordées, même si elles peuvent partager l’accès simultané avec les détenteurs de verrous de lecteur existants ; Cela permet de protéger les auteurs contre les blocages indéfinis par les lecteurs.Their requests are not granted, even though they could share concurrent access with existing reader-lock holders; this helps protect writers against indefinite blockage by readers.

La plupart des méthodes d’acquisition de verrous sur ReaderWriterLock les valeurs de délai d’attente Accept.Most methods for acquiring locks on a ReaderWriterLock accept time-out values. Utilisez des délais d’attente pour éviter les interblocages dans votre application.Use time-outs to avoid deadlocks in your application. Par exemple, un thread peut acquérir le verrou de writer sur une ressource, puis demander un verrou de lecteur sur une deuxième ressource ; en attendant, un autre thread peut acquérir le verrou de writer sur la deuxième ressource et demander un verrou de lecteur sur la première.For example, a thread might acquire the writer lock on one resource and then request a reader lock on a second resource; in the meantime, another thread might acquire the writer lock on the second resource, and request a reader lock on the first. À moins que les délais ne soient utilisés, les threads se bloquent.Unless time-outs are used, the threads deadlock.

Si l’intervalle de délai d’attente expire et que la demande de verrou n’a pas été accordée, la méthode retourne le contrôle au thread ApplicationExceptionappelant en levant un.If the time-out interval expires and the lock request has not been granted, the method returns control to the calling thread by throwing an ApplicationException. Un thread peut intercepter cette exception et déterminer l’action à entreprendre ensuite.A thread can catch this exception and determine what action to take next.

Les délais d’attente sont exprimés en millisecondes.Time-outs are expressed in milliseconds. Si vous utilisez un System.TimeSpan pour spécifier le délai d’attente, la valeur utilisée est le nombre total de millisecondes entières représenté TimeSpanpar.If you use a System.TimeSpan to specify the time-out, the value used is the total number of whole milliseconds represented by the TimeSpan. Le tableau suivant indique les valeurs de délai d’attente valides, en millisecondes.The following table shows the valid time-out values in milliseconds.

ValueValue DescriptionDescription
-1-1 Le thread attend que le verrou soit acquis, quel que soit le temps nécessaire.The thread waits until the lock is acquired, regardless of how long it takes. Pour les méthodes qui spécifient des délais d’expiration entiers, la constante Infinite peut être utilisée.For methods that specify integer time-outs, the constant Infinite can be used.
00 Le thread n’attend pas pour acquérir le verrou.The thread does not wait to acquire the lock. Si le verrou ne peut pas être acquis immédiatement, la méthode retourne.If the lock cannot be acquired immediately, the method returns.
>0>0 Nombre de millisecondes à attendre.The number of milliseconds to wait.

À l’exception de-1, les valeurs de délai d’attente négatives ne sont pas autorisées.With the exception of -1, negative time-out values are not allowed. Si vous spécifiez un entier négatif autre que-1, une valeur de délai d’attente de zéro est utilisée à la place.If you specify a negative integer other than -1, a time-out value of zero is used instead. (Autrement dit, la méthode retourne sans attendre, si le verrou ne peut pas être acquis immédiatement.) Si vous spécifiez TimeSpan un qui représente un nombre négatif de millisecondes autre que-1, ArgumentOutOfRangeException est levée.(That is, the method returns without waiting, if the lock cannot be acquired immediately.) If you specify a TimeSpan that represents a negative number of milliseconds other than -1, ArgumentOutOfRangeException is thrown.

Constructeurs

ReaderWriterLock() ReaderWriterLock() ReaderWriterLock() ReaderWriterLock()

Initialise une nouvelle instance de la classe ReaderWriterLock.Initializes a new instance of the ReaderWriterLock class.

Propriétés

IsReaderLockHeld IsReaderLockHeld IsReaderLockHeld IsReaderLockHeld

Obtient une valeur indiquant si le thread en cours détient un verrou de lecteur.Gets a value indicating whether the current thread holds a reader lock.

IsWriterLockHeld IsWriterLockHeld IsWriterLockHeld IsWriterLockHeld

Obtient une valeur indiquant si le thread en cours détient le verrou de writer.Gets a value indicating whether the current thread holds the writer lock.

WriterSeqNum WriterSeqNum WriterSeqNum WriterSeqNum

Obtient le numéro de séquence actuel.Gets the current sequence number.

Méthodes

AcquireReaderLock(Int32) AcquireReaderLock(Int32) AcquireReaderLock(Int32) AcquireReaderLock(Int32)

Acquiert un verrou de lecteur en utilisant une valeur Int32 comme délai d'attente.Acquires a reader lock, using an Int32 value for the time-out.

AcquireReaderLock(TimeSpan) AcquireReaderLock(TimeSpan) AcquireReaderLock(TimeSpan) AcquireReaderLock(TimeSpan)

Acquiert un verrou de lecteur en utilisant une valeur TimeSpan comme délai d'attente.Acquires a reader lock, using a TimeSpan value for the time-out.

AcquireWriterLock(Int32) AcquireWriterLock(Int32) AcquireWriterLock(Int32) AcquireWriterLock(Int32)

Acquiert un verrou de writer en utilisant une valeur Int32 comme délai d'attente.Acquires the writer lock, using an Int32 value for the time-out.

AcquireWriterLock(TimeSpan) AcquireWriterLock(TimeSpan) AcquireWriterLock(TimeSpan) AcquireWriterLock(TimeSpan)

Acquiert un verrou de writer en utilisant une valeur TimeSpan comme délai d'attente.Acquires the writer lock, using a TimeSpan value for the time-out.

AnyWritersSince(Int32) AnyWritersSince(Int32) AnyWritersSince(Int32) AnyWritersSince(Int32)

Indique si le verrou de writer a été accordé à un thread depuis l'obtention du numéro de séquence.Indicates whether the writer lock has been granted to any thread since the sequence number was obtained.

DowngradeFromWriterLock(LockCookie) DowngradeFromWriterLock(LockCookie) DowngradeFromWriterLock(LockCookie) DowngradeFromWriterLock(LockCookie)

Restaure le verrou du thread à l'état qu'il avait avant l'appel à UpgradeToWriterLock(Int32).Restores the lock status of the thread to what it was before UpgradeToWriterLock(Int32) was called.

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

Détermine si l'objet spécifié est identique à l'objet actuel.Determines whether the specified object is equal to the current object.

(Inherited from Object)
Finalize() Finalize() Finalize() Finalize()

Vérifie que les ressources sont libérées et que toute autre opération de nettoyage est effectuée quand le garbage collector récupère l'objet ReaderWriterLock.Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the ReaderWriterLock object.

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

Fait office de fonction de hachage par défaut.Serves as the default hash function.

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

Obtient le Type de l'instance actuelle.Gets the Type of the current instance.

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

Crée une copie superficielle de l'objet Object actuel.Creates a shallow copy of the current Object.

(Inherited from Object)
ReleaseLock() ReleaseLock() ReleaseLock() ReleaseLock()

Libère le verrou quel que soit le nombre de fois où il a été acquis par le thread.Releases the lock, regardless of the number of times the thread acquired the lock.

ReleaseReaderLock() ReleaseReaderLock() ReleaseReaderLock() ReleaseReaderLock()

Décrémente le nombre de verrous.Decrements the lock count.

ReleaseWriterLock() ReleaseWriterLock() ReleaseWriterLock() ReleaseWriterLock()

Décrémente le nombre de verrous sur le verrou de writer.Decrements the lock count on the writer lock.

RestoreLock(LockCookie) RestoreLock(LockCookie) RestoreLock(LockCookie) RestoreLock(LockCookie)

Restaure l'état de verrou du thread au moment précédant l'appel à ReleaseLock().Restores the lock status of the thread to what it was before calling ReleaseLock().

ToString() ToString() ToString() ToString()

Retourne une chaîne qui représente l'objet actuel.Returns a string that represents the current object.

(Inherited from Object)
UpgradeToWriterLock(Int32) UpgradeToWriterLock(Int32) UpgradeToWriterLock(Int32) UpgradeToWriterLock(Int32)

Met à niveau un verrou de lecteur vers le verrou de writer en utilisant une valeur Int32 pour définir le délai d'attente.Upgrades a reader lock to the writer lock, using an Int32 value for the time-out.

UpgradeToWriterLock(TimeSpan) UpgradeToWriterLock(TimeSpan) UpgradeToWriterLock(TimeSpan) UpgradeToWriterLock(TimeSpan)

Met à niveau un verrou de lecteur vers le verrou de writer en utilisant une valeur TimeSpan pour définir le délai d'attente.Upgrades a reader lock to the writer lock, using a TimeSpan value for the time-out.

S’applique à

Cohérence de thread

Ce type est thread-safe.This type is thread safe.

Voir aussi