ReaderWriterLock Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Определяет блокировку, которая поддерживает один пишущий поток и несколько читающих.
public ref class ReaderWriterLock sealed : System::Runtime::ConstrainedExecution::CriticalFinalizerObject
public ref class ReaderWriterLock sealed
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
public sealed class ReaderWriterLock
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class ReaderWriterLock : System.Runtime.ConstrainedExecution.CriticalFinalizerObject
type ReaderWriterLock = class
inherit CriticalFinalizerObject
type ReaderWriterLock = class
[<System.Runtime.InteropServices.ComVisible(true)>]
type ReaderWriterLock = class
inherit CriticalFinalizerObject
Public NotInheritable Class ReaderWriterLock
Inherits CriticalFinalizerObject
Public NotInheritable Class ReaderWriterLock
- Наследование
- Наследование
-
ReaderWriterLock
- Атрибуты
Примеры
В следующем примере показано, как использовать ReaderWriterLock для защиты общего ресурса целочисленное значение с именем resource
, которое считывается одновременно и записывается исключительно несколькими потоками. Обратите внимание, что ReaderWriterLock класс объявлен на уровне класса, чтобы он был виден всем потокам.
// This example shows a ReaderWriterLock protecting a shared
// resource that is read concurrently and written exclusively
// by multiple threads.
// 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;
literal int numThreads = 26;
static bool running = true;
// Statistics.
static int readerTimeouts = 0;
static int writerTimeouts = 0;
static int reads = 0;
static int writes = 0;
static void ThreadProc()
{
Random^ rnd = gcnew Random;
// As long as a thread runs, it randomly selects
// various ways to read and write from the shared
// resource. Each of the methods demonstrates one
// or more features of ReaderWriterLock.
while ( running )
{
double action = rnd->NextDouble();
if ( action < .8 )
ReadFromResource( 10 );
else
if ( action < .81 )
ReleaseRestore( rnd, 50 );
else
if ( action < .90 )
UpgradeDowngrade( rnd, 100 );
else
WriteToResource( rnd, 100 );
}
}
// Shows how to request and release a reader lock, and
// how to handle time-outs.
static void ReadFromResource( int timeOut )
{
try
{
rwl->AcquireReaderLock( timeOut );
try
{
// It is safe for this thread to read from
// the shared resource.
Display( String::Format( "reads resource value {0}", resource ) );
Interlocked::Increment( reads );
}
finally
{
// Ensure that the lock is released.
rwl->ReleaseReaderLock();
}
}
catch ( ApplicationException^ )
{
// The reader lock request timed out.
Interlocked::Increment( readerTimeouts );
}
}
// Shows how to request and release the writer lock, and
// how to handle time-outs.
static void WriteToResource( Random^ rnd, int timeOut )
{
try
{
rwl->AcquireWriterLock( timeOut );
try
{
// It is safe for this thread to read or write
// from the shared resource.
resource = rnd->Next( 500 );
Display( String::Format( "writes resource value {0}", resource ) );
Interlocked::Increment( writes );
}
finally
{
// Ensure that the lock is released.
rwl->ReleaseWriterLock();
}
}
catch ( ApplicationException^ )
{
// The writer lock request timed out.
Interlocked::Increment( writerTimeouts );
}
}
// Shows how to request a reader lock, upgrade the
// reader lock to the writer lock, and downgrade to a
// reader lock again.
static void UpgradeDowngrade( Random^ rnd, int timeOut )
{
try
{
rwl->AcquireReaderLock( timeOut );
try
{
// It is safe for this thread to read from
// the shared resource.
Display( String::Format( "reads resource value {0}", resource ) );
Interlocked::Increment( reads );
// If it is necessary to write to the resource,
// you must either release the reader lock and
// then request the writer lock, or upgrade the
// reader lock. Note that upgrading the reader lock
// puts the thread in the write queue, behind any
// other threads that might be waiting for the
// writer lock.
try
{
LockCookie lc = rwl->UpgradeToWriterLock( timeOut );
try
{
// It is safe for this thread to read or write
// from the shared resource.
resource = rnd->Next( 500 );
Display( String::Format( "writes resource value {0}", resource ) );
Interlocked::Increment( writes );
}
finally
{
// Ensure that the lock is released.
rwl->DowngradeFromWriterLock( lc );
}
}
catch ( ApplicationException^ )
{
// The upgrade request timed out.
Interlocked::Increment( writerTimeouts );
}
// When the lock has been downgraded, it is
// still safe to read from the resource.
Display( String::Format( "reads resource value {0}", resource ) );
Interlocked::Increment( reads );
}
finally
{
// Ensure that the lock is released.
rwl->ReleaseReaderLock();
}
}
catch ( ApplicationException^ )
{
// The reader lock request timed out.
Interlocked::Increment( readerTimeouts );
}
}
// 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 );
}
}
// Helper method briefly displays the most recent
// thread action. Comment out calls to Display to
// get a better idea of throughput.
static void Display( String^ msg )
{
Console::Write( "Thread {0} {1}. \r", Thread::CurrentThread->Name, msg );
}
};
int main()
{
array<String^>^args = Environment::GetCommandLineArgs();
// Start a series of threads. Each thread randomly
// performs reads and writes on the shared resource.
array<Thread^>^t = gcnew array<Thread^>(Test::numThreads);
for ( int i = 0; i < Test::numThreads; i++ )
{
t[ i ] = gcnew Thread( gcnew ThreadStart( Test::ThreadProc ) );
t[ i ]->Name = gcnew String( Convert::ToChar( i + 65 ),1 );
t[ i ]->Start();
if ( i > 10 )
Thread::Sleep( 300 );
}
// Tell the threads to shut down, then wait until they all
// finish.
Test::running = false;
for ( int i = 0; i < Test::numThreads; i++ )
{
t[ i ]->Join();
}
// Display statistics.
Console::WriteLine( "\r\n {0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.", Test::reads, Test::writes, Test::readerTimeouts, Test::writerTimeouts );
Console::WriteLine( "Press ENTER to exit." );
Console::ReadLine();
return 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;
const int numThreads = 26;
static bool running = true;
// Statistics.
static int readerTimeouts = 0;
static int writerTimeouts = 0;
static int reads = 0;
static int writes = 0;
public static void Main()
{
// Start a series of threads to randomly read from and
// write to the shared resource.
Thread[] t = new Thread[numThreads];
for (int i = 0; i < numThreads; i++){
t[i] = new Thread(new ThreadStart(ThreadProc));
t[i].Name = new String((char)(i + 65), 1);
t[i].Start();
if (i > 10)
Thread.Sleep(300);
}
// Tell the threads to shut down and wait until they all finish.
running = false;
for (int i = 0; i < numThreads; i++)
t[i].Join();
// Display statistics.
Console.WriteLine("\n{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
reads, writes, readerTimeouts, writerTimeouts);
Console.Write("Press ENTER to exit... ");
Console.ReadLine();
}
static void ThreadProc()
{
Random rnd = new Random();
// Randomly select a way for the thread to read and write from the shared
// resource.
while (running) {
double action = rnd.NextDouble();
if (action < .8)
ReadFromResource(10);
else if (action < .81)
ReleaseRestore(rnd, 50);
else if (action < .90)
UpgradeDowngrade(rnd, 100);
else
WriteToResource(rnd, 100);
}
}
// Request and release a reader lock, and handle time-outs.
static void ReadFromResource(int timeOut)
{
try {
rwl.AcquireReaderLock(timeOut);
try {
// It is safe for this thread to read from the shared resource.
Display("reads resource value " + resource);
Interlocked.Increment(ref reads);
}
finally {
// Ensure that the lock is released.
rwl.ReleaseReaderLock();
}
}
catch (ApplicationException) {
// The reader lock request timed out.
Interlocked.Increment(ref readerTimeouts);
}
}
// Request and release the writer lock, and handle time-outs.
static void WriteToResource(Random rnd, int timeOut)
{
try {
rwl.AcquireWriterLock(timeOut);
try {
// It's safe for this thread to access from the shared resource.
resource = rnd.Next(500);
Display("writes resource value " + resource);
Interlocked.Increment(ref writes);
}
finally {
// Ensure that the lock is released.
rwl.ReleaseWriterLock();
}
}
catch (ApplicationException) {
// The writer lock request timed out.
Interlocked.Increment(ref writerTimeouts);
}
}
// Requests a reader lock, upgrades the reader lock to the writer
// lock, and downgrades it to a reader lock again.
static void UpgradeDowngrade(Random rnd, int timeOut)
{
try {
rwl.AcquireReaderLock(timeOut);
try {
// It's safe for this thread to read from the shared resource.
Display("reads resource value " + resource);
Interlocked.Increment(ref reads);
// To write to the resource, either release the reader lock and
// request the writer lock, or upgrade the reader lock. Upgrading
// the reader lock puts the thread in the write queue, behind any
// other threads that might be waiting for the writer lock.
try {
LockCookie lc = rwl.UpgradeToWriterLock(timeOut);
try {
// It's safe for this thread to read or write from the shared resource.
resource = rnd.Next(500);
Display("writes resource value " + resource);
Interlocked.Increment(ref writes);
}
finally {
// Ensure that the lock is released.
rwl.DowngradeFromWriterLock(ref lc);
}
}
catch (ApplicationException) {
// The upgrade request timed out.
Interlocked.Increment(ref writerTimeouts);
}
// If the lock was downgraded, it's still safe to read from the resource.
Display("reads resource value " + resource);
Interlocked.Increment(ref reads);
}
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.
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);
}
}
// Helper method briefly displays the most recent thread action.
static void Display(string msg)
{
Console.Write("Thread {0} {1}. \r", Thread.CurrentThread.Name, msg);
}
}
' 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
Const numThreads As Integer = 26
Private running As Boolean = True
' Statistics.
Private readerTimeouts As Integer = 0
Private writerTimeouts As Integer = 0
Private reads As Integer = 0
Private writes As Integer = 0
Public Sub Main()
' Start a series of threads to randomly read from and
' write to the shared resource.
Dim t(numThreads - 1) As Thread
Dim i As Integer
For i = 0 To numThreads - 1
t(i) = New Thread(New ThreadStart(AddressOf ThreadProc))
t(i).Name = Chr(i + 65)
t(i).Start()
If i > 10 Then
Thread.Sleep(300)
End If
Next
' Tell the threads to shut down and wait until they all finish.
running = False
For i = 0 To numThreads - 1
t(i).Join()
Next
' Display statistics.
Console.WriteLine(vbCrLf & "{0} reads, {1} writes, {2} reader time-outs, {3} writer time-outs.",
reads, writes, readerTimeouts, writerTimeouts)
Console.Write("Press ENTER to exit... ")
Console.ReadLine()
End Sub
Sub ThreadProc()
Dim rnd As New Random
' Randomly select a way for the thread to read and write from the shared
' resource.
While running
Dim action As Double = rnd.NextDouble()
If action < 0.8 Then
ReadFromResource(10)
ElseIf action < 0.81 Then
ReleaseRestore(rnd, 50)
ElseIf action < 0.9 Then
UpgradeDowngrade(rnd, 100)
Else
WriteToResource(rnd, 100)
End If
End While
End Sub
' Request and release a reader lock, and handle time-outs.
Sub ReadFromResource(timeOut As Integer)
Try
rwl.AcquireReaderLock(timeOut)
Try
' It's safe for this thread to read from the shared resource.
Display("reads resource value " & resource)
Interlocked.Increment(reads)
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
' Request and release the writer lock, and handle time-outs.
Sub WriteToResource(rnd As Random, timeOut As Integer)
Try
rwl.AcquireWriterLock(timeOut)
Try
' It's safe for this thread to read or write from the shared resource.
resource = rnd.Next(500)
Display("writes resource value " & resource)
Interlocked.Increment(writes)
Finally
' Ensure that the lock is released.
rwl.ReleaseWriterLock()
End Try
Catch ex As ApplicationException
' The writer lock request timed out.
Interlocked.Increment(writerTimeouts)
End Try
End Sub
' Requests a reader lock, upgrades the reader lock to the writer
' lock, and downgrades it to a reader lock again.
Sub UpgradeDowngrade(rnd As Random, timeOut As Integer)
Try
rwl.AcquireReaderLock(timeOut)
Try
' It's safe for this thread to read from the shared resource.
Display("reads resource value " & resource)
Interlocked.Increment(reads)
' To write to the resource, either release the reader lock and
' request the writer lock, or upgrade the reader lock. Upgrading
' the reader lock puts the thread in the write queue, behind any
' other threads that might be waiting for the writer lock.
Try
Dim lc As LockCookie = rwl.UpgradeToWriterLock(timeOut)
Try
' It's safe for this thread to read or write from the shared resource.
resource = rnd.Next(500)
Display("writes resource value " & resource)
Interlocked.Increment(writes)
Finally
' Ensure that the lock is released.
rwl.DowngradeFromWriterLock(lc)
End Try
Catch ex As ApplicationException
' The upgrade request timed out.
Interlocked.Increment(writerTimeouts)
End Try
' If the lock was downgraded, it's still safe to read from the resource.
Display("reads resource value " & resource)
Interlocked.Increment(reads)
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
' 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
' Helper method briefly displays the most recent thread action.
Sub Display(msg As String)
Console.Write("Thread {0} {1}. " & vbCr, Thread.CurrentThread.Name, msg)
End Sub
End Module
Комментарии
Важно!
Платформа .NET Framework имеет две блокировки средства чтения и записи: ReaderWriterLockSlim и ReaderWriterLock. Мы рекомендуем применять ReaderWriterLockSlim при любых новых разработках. ReaderWriterLockSlim действует так же, как и ReaderWriterLock, но с более простыми правилами рекурсии и изменения состояния блокировки. ReaderWriterLockSlim позволяет избежать многих ситуаций взаимоблокировки. Кроме того, производительность ReaderWriterLockSlim значительно выше, чем у ReaderWriterLock.
ReaderWriterLock используется для синхронизации доступа к ресурсу. В любой момент времени он обеспечивает либо одновременный доступ на чтение для нескольких потоков, либо доступ на запись для одного потока. В ситуации, когда ресурс изменяется нечасто, обеспечивает лучшую ReaderWriterLock
пропускную способность, чем простая блокировка один за раз, например Monitor.
ReaderWriterLock
Лучше всего работает в тех случаях, когда большинство обращений — это операции чтения, в то время как записи выполняются редко и имеют короткую длительность. Несколько модулей чтения чередуются с одними модулями записи, поэтому ни читатели, ни авторы не блокируются на длительное время.
Примечание
Длительное хранение блокировок средства чтения или записи приведет к нехватке других потоков. Для достижения оптимальной производительности рассмотрите возможность реструктуризации приложения, чтобы свести к минимуму длительность операций записи.
Поток может содержать блокировку чтения или блокировку записи, но не одновременно. Вместо освобождения блокировки средства чтения для получения блокировки модуля записи можно использовать UpgradeToWriterLock и DowngradeFromWriterLock.
Рекурсивные запросы на блокировку увеличивают число блокировок.
Читатели и записи помещаются в очередь отдельно. Когда поток снимает блокировку модуля записи, всем потокам, ожидающим в очереди чтения в этот момент, предоставляются блокировки чтения. когда все блокировки средства чтения были сняты, следующему потоку, ожидающим в очереди модуля записи( если таковые имеются), предоставляется блокировка модуля записи и т. д. Другими словами, ReaderWriterLock
чередуется между коллекцией читателей и одним модулем записи.
В то время как поток в очереди записи ожидает освобождения активных блокировок чтения, потоки, запрашивающие новые блокировки чтения, накапливаются в очереди чтения. Их запросы не предоставляются, несмотря на то, что они могут совместно использовать параллельный доступ с существующими держателями блокировки чтения; это помогает защитить записи от бессрочной блокировки со стороны читателей.
Большинство методов получения блокировок ReaderWriterLock
для принимают значения времени ожидания. Используйте тайм-ауты, чтобы избежать взаимоблокировок в приложении. Например, поток может получить блокировку записи для одного ресурса, а затем запросить блокировку чтения для второго ресурса; в то же время другой поток может получить блокировку записи для второго ресурса и запросить блокировку чтения для первого. Если время ожидания не используется, потоки взаимоблокируются.
Если истекает время ожидания и запрос на блокировку не был предоставлен, метод возвращает управление вызывающему потоку, вызывая ApplicationExceptionисключение . Поток может перехватывать это исключение и определять, какое действие следует предпринять далее.
Время ожидания выражается в миллисекундах. Если вы используете System.TimeSpan для указания времени ожидания, используется общее число миллисекундах, представленное TimeSpan. В следующей таблице показаны допустимые значения времени ожидания в миллисекундах.
Значение | Описание |
---|---|
-1 | Поток ожидает, пока не будет получена блокировка, независимо от того, сколько времени это займет. Для методов, указывающих целочисленное время ожидания, можно использовать константу Infinite . |
0 | Поток не ожидает получения блокировки. Если блокировка не может быть получена немедленно, метод возвращает . |
>0 | Время ожидания в миллисекундах. |
За исключением -1, отрицательные значения времени ожидания не допускаются. Если указать отрицательное целое число, отличное от -1, используется нулевое значение времени ожидания. (То есть метод возвращается без ожидания, если блокировка не может быть получена немедленно.) Если указать TimeSpan значение , представляющее отрицательное число миллисекундах, отличное от -1, ArgumentOutOfRangeException возникает исключение.
Конструкторы
ReaderWriterLock() |
Инициализирует новый экземпляр класса ReaderWriterLock. |
Свойства
IsReaderLockHeld |
Возвращает значение, указывающее, владеет ли текущий поток блокировкой чтения. |
IsWriterLockHeld |
Возвращает значение, указывающее, владеет ли текущий поток блокировкой записи. |
WriterSeqNum |
Возвращает текущий последовательный номер. |
Методы
AcquireReaderLock(Int32) |
Получает блокировку чтения, используя значение Int32 для задания времени ожидания. |
AcquireReaderLock(TimeSpan) |
Получает блокировку чтения, используя значение TimeSpan для задания времени ожидания. |
AcquireWriterLock(Int32) |
Получает блокировку записи, используя значение Int32 для задания времени ожидания. |
AcquireWriterLock(TimeSpan) |
Получает блокировку записи, используя значение TimeSpan для задания времени ожидания. |
AnyWritersSince(Int32) |
Показывает, была ли предоставлена блокировка записи какому-либо потоку со времени получения последовательного номера. |
DowngradeFromWriterLock(LockCookie) |
Возвращает состояние блокировки потока к тому, которое было до вызова метода UpgradeToWriterLock(Int32). |
Equals(Object) |
Определяет, равен ли указанный объект текущему объекту. (Унаследовано от Object) |
Finalize() |
Обеспечивает освобождение ресурсов и выполнение других завершающих операций, когда сборщик мусора восстанавливает объект ReaderWriterLock. |
GetHashCode() |
Служит хэш-функцией по умолчанию. (Унаследовано от Object) |
GetType() |
Возвращает объект Type для текущего экземпляра. (Унаследовано от Object) |
MemberwiseClone() |
Создает неполную копию текущего объекта Object. (Унаследовано от Object) |
ReleaseLock() |
Освобождает блокировку, независимо от количества ее получений потоком. |
ReleaseReaderLock() |
Уменьшает на единицу счетчик блокировок. |
ReleaseWriterLock() |
Уменьшает на единицу счетчик блокировок данной блокировки записи. |
RestoreLock(LockCookie) |
Возвращает состояние блокировки потока к тому, которое было до вызова метода ReleaseLock(). |
ToString() |
Возвращает строку, представляющую текущий объект. (Унаследовано от Object) |
UpgradeToWriterLock(Int32) |
Повышает уровень блокировки чтения до блокировки записи, используя значение Int32 для задания времени ожидания. |
UpgradeToWriterLock(TimeSpan) |
Повышает уровень блокировки чтения до блокировки записи, используя значение |
Применяется к
Потокобезопасность
Данный тип потокобезопасен.