ReaderWriterLock クラス

定義

単一ライターと複数リーダーをサポートするロックを定義します。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
継承
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 という 2 つのリーダー/ライター ロックがあります。The .NET Framework.NET Framework has two reader-writer locks, ReaderWriterLockSlim and ReaderWriterLock. すべての新規開発で、ReaderWriterLockSlim を使用することをお勧めします。ReaderWriterLockSlim is recommended for all new development. ReaderWriterLockSlimReaderWriterLock と似ていますが、再帰の規則や、ロック状態のアップグレードおよびダウングレードの規則が簡素化されています。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 のパフォーマンスは ReaderWriterLock と比較して格段に優れています。In addition, the performance of ReaderWriterLockSlim is significantly better than ReaderWriterLock.

ReaderWriterLockは、リソースへのアクセスを同期するために使用されます。ReaderWriterLock is used to synchronize access to a resource. 任意の時点で、複数のスレッドに対する同時読み取りアクセス、または1つのスレッドに対する書き込みアクセスが許可されます。At any given time, it allows either concurrent read access for multiple threads, or write access for a single thread. リソースが頻繁ReaderWriterLockに変更されない場合、では、などの単純な1回限りのロック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. 複数のリーダーが1つのライターと交互に使用されるため、読み取りと書き込みのどちらも長期間ブロックされません。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. ライターロックを取得するためにリーダーロックを解放する代わりに、とUpgradeToWriterLock DowngradeFromWriterLockを使用できます。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リーダーのコレクションと1つのライターを交互に区別します。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. たとえば、あるスレッドが1つのリソースに対してライターロックを取得し、2番目のリソースにリーダーロックを要求する場合があります。その間に、別のスレッドが2番目のリソースのライターロックを取得し、最初にリーダーロックを要求する場合があります。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. 整数のタイムアウトを指定するメソッドの場合は、 Infinite定数を使用できます。For 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 以外の負の整数を指定した場合は、代わりにタイムアウト値0が使用されます。If you specify a negative integer other than -1, a time-out value of zero is used instead. (つまり、ロックをすぐに取得できない場合、メソッドは待機せずに制御を戻します)。-1 以外のTimeSpan負のミリ秒数を表すを指定すると、 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()

現在のインスタンスの Type を取得します。Gets 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.

こちらもご覧ください