Подтвердить что ты не робот

Блокировка, которая позволит нескольким читателям в С#

У меня есть следующий код:

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?

4b9b3361

Ответ 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
}

Это позволяет нескольким читателям дождаться завершения загрузчика данных и затем прочитать его. Если сбор не является потокобезопасным, вам нужно добавить еще один объект блокировки или использовать другую конструкцию синхронизации.