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
; в противном случае можно использовать кэшированные сведения. Этот метод полезен при чтении информации, защищенной блокировкой, является дорогостоящим; например, выполнение запроса к базе данных.
Вызывающий объект должен содержать блокировку средства чтения или блокировку записи, чтобы порядковый номер был полезен.