ReaderWriterLock.WriterSeqNum 屬性

定義

取得目前的序號。

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

屬性值

目前的序號。

範例

下列程式碼範例示範如何使用 WriterSeqNum 屬性和 AnyWritersSince 方法,判斷自目前線程上次保留寫入器鎖定以來,是否有另一個執行緒取得受保護資源的寫入器鎖定。

此程式碼是類別所提供較大範例的 ReaderWriterLock 一部分。

// 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

備註

每當執行緒取得寫入器鎖定時,序號就會增加。 如果您想要判斷其他執行緒是否同時取得寫入器鎖定,可以儲存序號並稍後傳遞 AnyWritersSince 至 。

您可以使用 WriterSeqNum 來改善應用程式效能。 例如,執行緒可能會在保留讀取器鎖定時快取它取得的資訊。 釋放和更新版本重新取得鎖定之後,執行緒可以藉由呼叫 AnyWritersSince 來判斷其他執行緒是否已寫入資源;如果不是,則可以使用快取的資訊。 讀取受鎖定保護的資訊時,這項技術相當實用;例如,執行資料庫查詢。

呼叫端必須保存讀取器鎖定或寫入器鎖定,才能讓序號很有用。

適用於

另請參閱