2012-10-17 9 views
12

Ich habe den folgenden Code:sperren, die mehrere Leser in C# ermöglicht

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

Ich möchte nicht, dass Menschen zu ermöglichen, die Daten zu lesen, während sie aus der Datenbank geladen wird ist, so habe ich eine lock in ReadData. Wenn jedoch mehrere Personen gleichzeitig ReadData anrufen, kann nur ein Anruf gleichzeitig ausgeführt werden.

Gibt es eine Möglichkeit, ich gleichzeitige Anrufe an ReadData zulassen kann, aber Leser blockieren, wenn LoadData ausgeführt wird?

Antwort

13

Die Klassen ReaderWriterLock und unterstützen diesen Anwendungsfall. Verwenden Sie die "Slim" -Version, es sei denn, Sie benötigen Unterstützung vor Version 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

Gut zu wissen. Cooles Zeug! – joshgo

+0

Sieht perfekt aus! Ich dachte, dass es so etwas in .NET Framework geben würde. –

1

Versuchen die ManualResetEvent mit:

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 
} 

Diese mehrere Leser ermöglicht die Datenlader zu warten seine Arbeit zu beenden und dann gleichzeitig gelesen. Wenn die Sammlung nicht Thread-sicher ist, müssen Sie ein anderes Sperrobjekt hinzufügen oder ein anderes Synchronisierungskonstrukt verwenden.

+0

Das ist auch eine gute Antwort, obwohl ich * glaube * wenn jemand 'LoadData()' während Daten gelesen wurde, könnte es einige Probleme geben. Ich möchte, dass alles blockiert wird, während Daten geladen werden. –

+0

@MikeChristensen guten Punkt, wie Sie darauf hingewiesen: Dies ist nur eine Alternative, die mit etwas Basteln arbeiten könnte. – Kiril