2012-10-17 23 views
12

Tôi có đoạn mã sau:Khóa này sẽ cho phép nhiều độc giả trong 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 
    } 
} 

Tôi không muốn để cho phép mọi người đọc dữ liệu trong khi nó đang được nạp từ cơ sở dữ liệu, vì vậy tôi đặt một lock trong ReadData. Tuy nhiên, ngay bây giờ nếu nhiều người gọi ReadData cùng một lúc, chỉ một cuộc gọi có thể chạy cùng một lúc.

Có cách nào tôi có thể cho phép các cuộc gọi đồng thời tới ReadData nhưng chặn người đọc khi LoadData đang được chạy?

Trả lời

13

Các lớp ReaderWriterLockReaderWriterLockSlim hỗ trợ trường hợp sử dụng đó. Sử dụng phiên bản 'Slim' trừ khi bạn cần hỗ trợ trước 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

Điều cần biết. Những thứ tuyệt vời! – joshgo

+0

Có vẻ hoàn hảo! Tôi đã tìm ra một thứ như thế này trong .NET Framework. –

1

Hãy thử sử dụng 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 
} 

này cho phép nhiều độc giả chờ đợi nạp dữ liệu để kết thúc công việc của mình và sau đó đồng thời đọc. Nếu bộ sưu tập không phải là luồng an toàn, thì bạn cần phải thêm một đối tượng khóa khác hoặc sử dụng một cấu trúc đồng bộ hóa khác.

+0

Đây cũng là một câu trả lời hay, mặc dù tôi * tin rằng nếu ai đó gọi là 'LoadData() 'trong khi dữ liệu được đọc, thì có thể có một số vấn đề. Tôi muốn mọi thứ bị chặn trong khi dữ liệu đang được tải. –

+0

@MikeChristensen tốt điểm, như bạn chỉ ra: đây chỉ là một thay thế mà có thể làm việc với một số mày mò. – Kiril

Các vấn đề liên quan