ReaderWriterLock 類別

定義

定義鎖定,它支援單一寫入器和多重讀取器。Defines a lock that supports single writers and multiple readers.

public ref class ReaderWriterLock sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject
public ref class ReaderWriterLock sealed
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
public sealed class ReaderWriterLock
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
type ReaderWriterLock = class
    inherit CriticalFinalizerObject
type ReaderWriterLock = class
Public NotInheritable Class ReaderWriterLock
Inherits CriticalFinalizerObject
Public NotInheritable Class ReaderWriterLock
繼承
ReaderWriterLock
繼承
ReaderWriterLock
屬性

範例

下列範例示範如何使用 ReaderWriterLock 來保護共用資源,這是名為 resource的整數值,它是由多個執行緒以獨佔方式讀取及寫入。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. 請注意,ReaderWriterLock 是在類別層級宣告,讓所有線程都可以看到它。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

備註

重要

.NET Framework.NET Framework 擁有 ReaderWriterLockSlimReaderWriterLock 這兩個 Reader-Writer 鎖定。The .NET Framework.NET Framework has two reader-writer locks, ReaderWriterLockSlim and ReaderWriterLock. 建議針對所有新的開發使用 ReaderWriterLockSlimReaderWriterLockSlim is recommended for all new development. ReaderWriterLockSlim 類似於 ReaderWriterLock,但是它有遞迴以及升級和降級鎖定狀態的簡化規則。ReaderWriterLockSlim is similar to ReaderWriterLock, but it has simplified rules for recursion and for upgrading and downgrading lock state. ReaderWriterLockSlim 可避免可能發生死結的許多情況。ReaderWriterLockSlim avoids many cases of potential deadlock. 此外,ReaderWriterLockSlim 的效能明顯優於 ReaderWriterLockIn addition, the performance of ReaderWriterLockSlim is significantly better than ReaderWriterLock.

ReaderWriterLock 可用來同步處理對資源的存取。ReaderWriterLock is used to synchronize access to a resource. 在任何指定的時間,它允許多個執行緒的並行讀取存取,或單一線程的寫入存取權。At any given time, it allows either concurrent read access for multiple threads, or write access for a single thread. 在資源不常變更的情況下,ReaderWriterLock 提供比簡單的一次性鎖定(例如 Monitor)更好的輸送量。In a situation where a resource is changed infrequently, a ReaderWriterLock provides better throughput than a simple one-at-a-time lock, such as Monitor.

ReaderWriterLock 最適合用來讀取大部分的存取,而寫入則不常和短時間。ReaderWriterLock works best where most accesses are reads, while writes are infrequent and of short duration. 具有單一寫入器的多個讀取器,因此讀取器或寫入器不會長時間遭到封鎖。Multiple readers alternate with single writers, so that neither readers nor writers are blocked for long periods.

注意

保留讀取器鎖定或長時間的寫入器鎖定將會使其他執行緒。Holding reader locks or writer locks for long periods will starve other threads. 為了達到最佳效能,請考慮重建您的應用程式,將寫入的持續時間減至最少。For best performance, consider restructuring your application to minimize the duration of writes.

執行緒可以保存讀取器鎖定或寫入器鎖定,但不能同時保有兩者。A thread can hold a reader lock or a writer lock, but not both at the same time. 您可以使用 UpgradeToWriterLockDowngradeFromWriterLock,而不是釋放讀取器鎖定來取得寫入器鎖定。Instead of releasing a reader lock in order to acquire the writer lock, you can use UpgradeToWriterLock and DowngradeFromWriterLock.

遞迴鎖定要求會增加鎖定的鎖定計數。Recursive lock requests increase the lock count on a lock.

讀取器和寫入器會分別排入佇列。Readers and writers are queued separately. 當執行緒釋放寫入器鎖定時,在該瞬間等待讀取器佇列中的所有線程都會被授與讀取器鎖定;當所有這些讀取器鎖定都已釋放時,在寫入器佇列中等待的下一個執行緒(如果有的話)會被授與寫入器鎖定,依此類推。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. 換句話說,ReaderWriterLock 會在讀取器集合和一個寫入器之間替換。In other words, ReaderWriterLock alternates between a collection of readers, and one writer.

當寫入器佇列中的執行緒正在等候釋放讀取器鎖定時,要求新讀取器鎖定的執行緒會累積在讀取器佇列中。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. 即使他們可以與現有讀取器鎖定持有者共用平行存取,也不會授與他們的要求;這有助於保護寫入者免于讀取器不受封鎖。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.

ReaderWriterLock 上取得鎖定的大部分方法都接受超時值。Most methods for acquiring locks on a ReaderWriterLock accept time-out values. 使用超時來避免應用程式中發生鎖死。Use time-outs to avoid deadlocks in your application. 例如,執行緒可能會在一個資源上取得寫入器鎖定,然後在第二個資源上要求讀取器鎖定;同時,另一個執行緒可能會取得第二個資源的寫入器鎖定,並要求第一個的讀取器鎖定。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. 除非使用時間輸出,否則執行緒會鎖死。Unless time-outs are used, the threads deadlock.

如果逾時間隔到期,且尚未授與鎖定要求,方法會擲回 ApplicationException,以將控制權傳回呼叫執行緒。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. 執行緒可以攔截這個例外狀況,並決定接下來要採取的動作。A thread can catch this exception and determine what action to take next.

超時時間以毫秒為單位表示。Time-outs are expressed in milliseconds. 如果您使用 System.TimeSpan 來指定超時,則使用的值是 TimeSpan所表示的完整毫秒總數。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. 下表顯示有效的超時值(以毫秒為單位)。The following table shows the valid time-out values in milliseconds.

Value 描述Description
-1-1 執行緒會等待直到取得鎖定為止,不論其花費多久。The thread waits until the lock is acquired, regardless of how long it takes. 對於指定整數時間輸出的方法,可以使用常數 InfiniteFor methods that specify integer time-outs, the constant Infinite can be used.
00 執行緒不會等候取得鎖定。The thread does not wait to acquire the lock. 如果無法立即取得鎖定,則方法會傳回。If the lock cannot be acquired immediately, the method returns.
>0>0 要等候的毫秒數。The number of milliseconds to wait.

除了-1 以外,不允許負的超時值。With the exception of -1, negative time-out values are not allowed. 如果您指定-1 以外的負整數,則會改用超時值零。If you specify a negative integer other than -1, a time-out value of zero is used instead. (也就是說,如果無法立即取得鎖定,方法就會傳回,而不會等候。)如果您指定的 TimeSpan 代表負的毫秒數,但不是-1,則會擲回 ArgumentOutOfRangeException(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.

建構函式

ReaderWriterLock()

初始化 ReaderWriterLock 類別的新執行個體。Initializes a new instance of the ReaderWriterLock class.

屬性

IsReaderLockHeld

取得值,指出目前的執行緒是否掌握讀取器的鎖定。Gets a value indicating whether the current thread holds a reader lock.

IsWriterLockHeld

取得值,指出目前的執行緒是否掌握寫入器的鎖定。Gets a value indicating whether the current thread holds the writer lock.

WriterSeqNum

取得目前的序號。Gets the current sequence number.

方法

AcquireReaderLock(Int32)

使用逾時值 Int32 取得讀取器的鎖定。Acquires a reader lock, using an Int32 value for the time-out.

AcquireReaderLock(TimeSpan)

使用逾時值 TimeSpan 取得讀取器的鎖定。Acquires a reader lock, using a TimeSpan value for the time-out.

AcquireWriterLock(Int32)

使用逾時值 Int32 取得寫入器的鎖定。Acquires the writer lock, using an Int32 value for the time-out.

AcquireWriterLock(TimeSpan)

使用逾時值 TimeSpan 取得寫入器的鎖定。Acquires the writer lock, using a TimeSpan value for the time-out.

AnyWritersSince(Int32)

指示取得序號之後有無將寫入器鎖定授與至任何執行緒。Indicates whether the writer lock has been granted to any thread since the sequence number was obtained.

DowngradeFromWriterLock(LockCookie)

將執行緒的鎖定狀態還原到呼叫 UpgradeToWriterLock(Int32) 之前的狀態。Restores the lock status of the thread to what it was before UpgradeToWriterLock(Int32) was called.

Equals(Object)

判斷指定的物件是否等於目前的物件。Determines whether the specified object is equal to the current object.

(繼承來源 Object)
Finalize()

確認釋出資源,並在記憶體回收行程回收 ReaderWriterLock 物件時執行其他清除作業。Ensures that resources are freed and other cleanup operations are performed when the garbage collector reclaims the ReaderWriterLock object.

GetHashCode()

作為預設雜湊函數。Serves as the default hash function.

(繼承來源 Object)
GetType()

取得目前執行個體的 TypeGets the Type of the current instance.

(繼承來源 Object)
MemberwiseClone()

建立目前 Object 的淺層複製。Creates a shallow copy of the current Object.

(繼承來源 Object)
ReleaseLock()

無論執行緒取得鎖定的次數為多少,都會釋放鎖定。Releases the lock, regardless of the number of times the thread acquired the lock.

ReleaseReaderLock()

減量鎖定計數。Decrements the lock count.

ReleaseWriterLock()

減量寫入器鎖定上的鎖定計數。Decrements the lock count on the writer lock.

RestoreLock(LockCookie)

將執行緒的鎖定狀態還原到呼叫 ReleaseLock() 之前的狀態。Restores the lock status of the thread to what it was before calling ReleaseLock().

ToString()

傳回代表目前物件的字串。Returns a string that represents the current object.

(繼承來源 Object)
UpgradeToWriterLock(Int32)

使用逾時值 Int32,將讀取器鎖定升級至寫入器鎖定。Upgrades a reader lock to the writer lock, using an Int32 value for the time-out.

UpgradeToWriterLock(TimeSpan)

使用逾時值 TimeSpan,將讀取器鎖定升級至寫入器鎖定。Upgrades a reader lock to the writer lock, using a TimeSpan value for the time-out.

適用於

執行緒安全性

此型別具備執行緒安全。This type is thread safe.

另請參閱