ReaderWriterLock.RestoreLock(LockCookie) メソッド
定義
重要
一部の情報は、リリース前に大きく変更される可能性があるプレリリースされた製品に関するものです。 Microsoft は、ここに記載されている情報について、明示または黙示を問わず、一切保証しません。
スレッドのロック ステータスを、ReleaseLock() を呼び出す前の状態に復元します。
public:
void RestoreLock(System::Threading::LockCookie % lockCookie);
public void RestoreLock (ref System.Threading.LockCookie lockCookie);
[System.Runtime.Versioning.UnsupportedOSPlatform("browser")]
public void RestoreLock (ref System.Threading.LockCookie lockCookie);
member this.RestoreLock : LockCookie -> unit
[<System.Runtime.Versioning.UnsupportedOSPlatform("browser")>]
member this.RestoreLock : LockCookie -> unit
Public Sub RestoreLock (ByRef lockCookie As LockCookie)
パラメーター
- lockCookie
- LockCookie
LockCookie によって戻される ReleaseLock()。
- 属性
例外
lockCookie
のアドレスは null ポインターです。
例
次のコード例は、 メソッドを使用 ReleaseLock して、スレッドによって取得された回数に関係なく、ロックを解放する方法と、後でロックの状態を復元する方法を示しています。
このコードは、 クラスに対して提供されるより大きな例の 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
注釈
によって RestoreLock
復元された状態には、再帰ロック数が含まれます。
別のスレッドがライター ロックを取得した後にリーダー ロックを復元しようとした場合、または別のスレッドがリーダー ロックまたはライター ロックを取得した後にライター ロックを復元しようとした場合、スレッドはブロックします。 はタイムアウトを受け入れないの RestoreLock
で、デッドロックの可能性を回避するように注意する必要があります。
注意事項
を呼び出す RestoreLock
前に、 の ReleaseLock呼び出し以降に取得されたすべてのロックが解放されていることを確認してください。 たとえば、スレッドがリーダー ロックを取得し、以前のライター ロックの復元を試みると、デッドロックが発生します。 このような追加のロックを検出するには、 と IsWriterLockHeld を使用IsReaderLockHeldします。
からUpgradeToWriterLock返された をLockCookie使用しないでください。
適用対象
こちらもご覧ください
.NET