Блокировка, которая позволит нескольким читателям в С#
У меня есть следующий код:
private static object _dbLock = new object();
public static void LoadData()
{
lock (_dbLock)
{
//Load data from the database
}
}
public static string ReadData(Guid key)
{
lock (_dbLock)
{
//Lookup key in data and return value
}
}
Я не хочу, чтобы люди могли читать данные во время загрузки из базы данных, поэтому я положил lock
в ReadData
. Тем не менее, прямо сейчас, если несколько человек звонят ReadData
в одно и то же время, сразу может запускаться только один вызов.
Есть ли способ разрешить одновременные вызовы ReadData
, но блокировать считыватели, когда выполняется LoadData
?
Ответы
Ответ 1
ReaderWriterLock
и ReaderWriterLockSlim
классы поддержка это использование случай. Используйте версию "Slim", если вам не нужна поддержка до 3.5.
private static ReaderWriterLockSlim _cacheLock = new ReaderWriterLockSlim();
public static void LoadData()
{
_cacheLock.EnterWriteLock();
try
{
// Load data from the database
}
finally
{
_cacheLock.ExitWriteLock();
}
}
public static string ReadData(Guid key)
{
_cacheLock.EnterReadLock();
try
{
// Lookup key in data and return value
}
finally
{
_cacheLock.ExitReadLock();
}
}
Ответ 2
Попробуйте использовать ManualResetEvent
:
private static object _dbLock = new object();
private static ManualResetEvent _mrse = new ManualResetEvent(true);
public static void LoadData()
{
lock (_dbLock)
{
_mrse.Reset();
//Load data from the database
_mrse.Set();
}
}
public static string ReadData(Guid key)
{
_mrse.Wait();
//Lookup key in data and return value
}
Это позволяет нескольким читателям дождаться завершения загрузчика данных и затем прочитать его. Если сбор не является потокобезопасным, вам нужно добавить еще один объект блокировки или использовать другую конструкцию синхронизации.