2009-11-08 28 views
7

Do các vấn đề về hiệu suất, tôi đã thay thế ReaderWriterLock bằng ReaderWriterLockSlim. Tôi gặp sự cố, do mã hoạt động chính xác khi sử dụng RWL.Thay thế ReaderWriterLock bằng ReaderWriterLockSLim - các sự cố

Như bạn thấy, đôi khi MethodA (mà có được một ghi khóa) gọi phương pháp khác (mà có được một đọc khóa). Phương pháp thứ hai cũng được gọi từ những nơi khác nhau, vì vậy không phải lúc nào cũng có va chạm khóa. Trước đây, khóa AcquiringRead không gây ra vấn đề đó.

Có giải pháp nào ngoại trừ việc đặt "nếu IsRWheld" không?

Vấn đề là một cái gì đó như thế:

class Avacado 
{ 
    ReaderWriterLockSlim _lock = new ReaderWriterLockSlim(); 

    void MethodA() 
    { 
     _lock.TryEnterWriteLock(-1); 
     LockedList.Add(someItem) 
     var result = MethodX(); 
     _lock.ExitWriteLock(); 
    } 

    object MethodX() 
    { 
     //if called from MethodA, it will throw an exception 
     _lock.TryEnterReadLock(-1); 

     //...some stuff with LockedList... 
     var result = LockList.Something(); 

     _lock.ExitReadLock(); 

     return result; 
    } 
} 

Trả lời

8

Các cuộc gọi đến MethodX từ MethodA đủ điều kiện nó như sử dụng đệ quy của khóa.
Xem những nhận xét trên MSDN page cho ReaderWriterLockSlim:

Theo mặc định, các trường hợp mới của ReaderWriterLockSlim được tạo ra với các LockRecursionPolicy.NoRecursion cờ và không cho phép đệ quy. Chính sách mặc định này được đề xuất cho tất cả phát triển mới, bởi vì đệ quy giới thiệu các biến chứng không cần thiết và làm cho mã của bạn dễ bị deadlocks. Để đơn giản hóa di cư từ dự án hiện có sử dụng Monitor hoặc ReaderWriterLock, bạn có thể sử dụng cờ LockRecursionPolicy.SupportsRecursion để tạo ra các trường hợp ReaderWriterLockSlim cho phép đệ quy.

4

Một điểm khác cần xem xét khi thay thế ReaderWriterLock bởi ReaderWriterLockSlim là sau đó thực hiện IDisposable.

Điều này có thể làm phức tạp thay thế - vì bất kỳ loại nào sở hữu số ReaderWriterLockSlim cũng phải là IDisposable.