Udostępnij za pośrednictwem


ReaderWriterLock.WriterSeqNum Właściwość

Definicja

Pobiera bieżący numer sekwencji.

public:
 property int WriterSeqNum { int get(); };
public int WriterSeqNum { get; }
member this.WriterSeqNum : int
Public ReadOnly Property WriterSeqNum As Integer

Wartość właściwości

Int32

Bieżący numer sekwencji.

Przykłady

Poniższy przykład kodu pokazuje, jak używać WriterSeqNum właściwości i AnyWritersSince metody w celu określenia, czy inny wątek nabył blokadę składnika zapisywania na chronionym zasobie, ponieważ bieżący wątek ostatnio przechowywał blokadę modułu zapisywania.

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

// 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;
// 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;
' 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
// 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( Random^ rnd, 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 );
   }

}
// 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(Random rnd, 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);
   }
}
' 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(rnd As Random ,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
};
}
End Module

Uwagi

Liczba sekwencyjna zwiększa się za każdym razem, gdy wątek uzyskuje blokadę modułu zapisywania. Możesz zapisać numer sekwencji i przekazać go w AnyWritersSince późniejszym czasie, jeśli chcesz określić, czy inne wątki nabyły blokadę modułu zapisywania w międzyczasie.

Możesz użyć WriterSeqNum polecenia , aby zwiększyć wydajność aplikacji. Na przykład wątek może przechowywać w pamięci podręcznej informacje, które uzyskuje podczas przechowywania blokady czytnika. Po zwolnieniu i późniejszym ponownym udostępnieniu blokady wątek może określić, czy inne wątki zostały zapisane w zasobie przez wywołanie metody AnyWritersSince; jeśli nie, można użyć informacji buforowanych. Ta technika jest przydatna podczas odczytywania informacji chronionych przez blokadę jest kosztowna; na przykład uruchomienie zapytania bazy danych.

Obiekt wywołujący musi mieć blokadę czytnika lub blokadę modułu zapisywania, aby numer sekwencji był przydatny.

Dotyczy

Zobacz też