ReaderWriterLock の最有力候補のようです。元の ReaderWriterLock にはパフォーマンスの問題があるため、使用するのに最適なクラス (ランタイムでサポートされている場合、3.0 以降と思われます) は ReaderWriterLockSlim です。
MSDN マガジンの著者の 1 人も RWLS クラスに関する問題に遭遇しました。ここでは詳しく説明しませんが、ここで確認できます。
次のコードが IDisposable の純粋主義者の怒りを買うことは承知していますが、実際には素晴らしい構文糖衣になることもあります。いずれにせよ、次のものが役立つ場合があります。
/// <summary>
/// Opens the specified reader writer lock in read mode,
/// specifying whether or not it may be upgraded.
/// </summary>
/// <param name="slim"></param>
/// <param name="upgradeable"></param>
/// <returns></returns>
public static IDisposable Read(this ReaderWriterLockSlim slim, bool upgradeable)
{
return new ReaderWriterLockSlimController(slim, true, upgradeable);
} // IDisposable Read
/// <summary>
/// Opens the specified reader writer lock in read mode,
/// and does not allow upgrading.
/// </summary>
/// <param name="slim"></param>
/// <returns></returns>
public static IDisposable Read(this ReaderWriterLockSlim slim)
{
return new ReaderWriterLockSlimController(slim, true, false);
} // IDisposable Read
/// <summary>
/// Opens the specified reader writer lock in write mode.
/// </summary>
/// <param name="slim"></param>
/// <returns></returns>
public static IDisposable Write(this ReaderWriterLockSlim slim)
{
return new ReaderWriterLockSlimController(slim, false, false);
} // IDisposable Write
private class ReaderWriterLockSlimController : IDisposable
{
#region Fields
private bool _closed = false;
private bool _read = false;
private ReaderWriterLockSlim _slim;
private bool _upgrade = false;
#endregion Fields
#region Constructors
public ReaderWriterLockSlimController(ReaderWriterLockSlim slim, bool read, bool upgrade)
{
_slim = slim;
_read = read;
_upgrade = upgrade;
if (_read)
{
if (upgrade)
{
_slim.EnterUpgradeableReadLock();
}
else
{
_slim.EnterReadLock();
}
}
else
{
_slim.EnterWriteLock();
}
} // ReaderWriterLockSlimController
~ReaderWriterLockSlimController()
{
Dispose();
} // ~ReaderWriterLockSlimController
#endregion Constructors
#region Methods
public void Dispose()
{
if (_closed)
return;
_closed = true;
if (_read)
{
if (_upgrade)
{
_slim.ExitUpgradeableReadLock();
}
else
{
_slim.ExitReadLock();
}
}
else
{
_slim.ExitWriteLock();
}
GC.SuppressFinalize(this);
} // void Dispose
#endregion Methods
} // Class ReaderWriterLockSlimController
それを拡張メソッド クラス (public static class [Name]) に入れて、次のように使用します。
using(myReaderWriterLockSlim.Read())
{
// Do read operations.
}
または
using(myReaderWriterLockSlim.Read(true))
{
// Read a flag.
if(flag)
{
using(myReaderWriterLockSlim.Write()) // Because we said Read(true).
{
// Do read/write operations.
}
}
}
または
using(myReaderWriterLockSlim.Write()) // This means you can also safely read.
{
// Do read/write operations.
}