Похоже, у вас есть главный кандидат на ReaderWriterLock. Лучший класс для использования (если ваша среда выполнения поддерживает его, я думаю, 3.0+) - это ReaderWriterLockSlim, поскольку у исходного ReaderWriterLock есть проблемы с производительностью.
Один из авторов журнала MSDN также столкнулся с проблемой с классом 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
Поместите это в класс метода расширения (открытый статический класс [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.
}