ReaderWriterLock.AnyWritersSince(Int32) 方法
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
指示取得序號之後有無將寫入器鎖定授與至任何執行緒。
public:
bool AnyWritersSince(int seqNum);
public bool AnyWritersSince (int seqNum);
member this.AnyWritersSince : int -> bool
Public Function AnyWritersSince (seqNum As Integer) As Boolean
參數
- seqNum
- Int32
序號。
傳回
如果取得序號之後有將寫入器鎖定授與至任何執行緒,則為 true
,否則為 false
。
範例
下列程式碼範例示範如何使用 AnyWritersSince 方法和 WriterSeqNum 屬性,判斷自目前線程上次保留寫入器鎖定之後,另一個執行緒是否取得受保護資源的寫入器鎖定。
此程式碼是提供給 類別之較大範例的 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
備註
您可以使用 WriterSeqNum 和 AnyWritersSince
來改善應用程式效能。 例如,執行緒可能會在保存讀取器鎖定時快取它取得的資訊。 釋放和更新版本重新取得鎖定之後,執行緒可以使用 AnyWritersSince
來判斷其他執行緒是否已在過渡期間寫入資源;如果沒有,可以使用快取的資訊。 這項技術很有用,其中讀取受鎖定保護的資訊相當昂貴;例如,執行資料庫查詢。
呼叫端必須保存讀取器鎖定或寫入器鎖定,序號才有用。