2012-10-17 12 views
12

Mam następujący kod:blokady, która pozwoli wielu czytelników w 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 
    } 
} 

nie chcę, aby ludzie do odczytu danych, podczas gdy jest ładowany z bazy danych, więc kładę lock w ReadData. Jednak w tej chwili, jeśli wiele osób zadzwoni pod numer ReadData w tym samym czasie, tylko jedno połączenie może zostać uruchomione jednocześnie.

Czy jest sposób, w jaki mogę zezwolić na jednoczesne połączenia z ReadData, ale czytniki bloków są uruchamiane, gdy LoadData jest uruchamiany?

Odpowiedz

13

Klasy ReaderWriterLock i ReaderWriterLockSlim obsługują ten przypadek użycia. Użyj wersji "Slim", chyba że potrzebujesz wsparcia przed 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

Dobrze wiedzieć. Fajne rzeczy! – joshgo

+0

Wygląda idealnie! Pomyślałem, że będzie coś takiego w .NET Framework. –

1

Spróbuj używając 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 
} 

Pozwala to wielu czytelników, aby czekać na ładowarce danych, aby zakończyć swoją pracę, a następnie równocześnie czytać. Jeśli kolekcja nie jest bezpieczna dla wątków, musisz dodać inny obiekt blokujący lub użyć innej konstrukcji synchronizacji.

+0

Jest to również dobra odpowiedź, chociaż * wierzę *, jeśli ktoś o nazwie 'LoadData()' podczas odczytu danych, może potencjalnie być pewne problemy. Chcę, aby wszystko zostało zablokowane podczas ładowania danych. –

+0

@MikeChristensen dobra uwaga, jak zauważyłeś: jest to tylko alternatywa, która może zadziałać przy niektórych majsterkowaniach. – Kiril

Powiązane problemy