2012-10-17 10 views
12

Ho il seguente codice:blocco che permetterà più lettori in C#

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 
    } 
} 

Non voglio permettere alle persone di leggere i dati mentre viene caricato dal database, quindi ho messo un lock in ReadData. Tuttavia, adesso se più persone chiamano allo stesso tempo ReadData, è possibile eseguire una sola chiamata alla volta.

C'è un modo per consentire le chiamate simultanee a ReadData ma bloccare i lettori quando viene eseguito LoadData?

risposta

13

Il supporto di classi ReaderWriterLock e ReaderWriterLockSlim che utilizza caso. Utilizzare la versione "Slim" a meno che non si abbia bisogno del supporto pre-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(); 
    } 
} 
+0

Buono a sapersi. Roba forte! – joshgo

+0

Sembra perfetto! Ho pensato che ci sarebbe qualcosa di simile in .NET Framework. –

1

Cercare di utilizzare il 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 
} 

Questo consente a più lettori di attendere per il caricatore di dati per completare il suo lavoro e poi leggere simultaneamente. Se la raccolta non è thread-safe, è necessario aggiungere un altro oggetto di blocco o utilizzare un altro costrutto di sincronizzazione.

+0

Questa è una buona risposta, anche se * credo * se qualcuno ha chiamato 'LoadData()' mentre i dati venivano letti, potrebbero esserci dei problemi. Voglio che tutto sia bloccato mentre i dati vengono caricati. –

+0

@MikeChristensen buon punto, come hai sottolineato: questa è solo un'alternativa che potrebbe funzionare con qualche armeggiare. – Kiril

Problemi correlati