2012-04-16 15 views
14

Tôi có dự án Visual Studio 2008 C# .NET 3.5 trong đó một lớp lắng nghe một lời gọi sự kiện từ một lớp khác được đa luồng. Tôi cần đảm bảo rằng sự kiện của tôi chỉ cho phép truy cập đồng thời tối đa 10 luồng. Chủ đề thứ 11 nên chặn cho đến khi một trong 10 kết thúc.Một chức năng chỉ cho phép N chủ đề đồng thời

myobj.SomeEvent += OnSomeEvent; 

private void OnSomeEvent(object sender, MyEventArgs args) 
{ 
    // allow up to 10 threads simultaneous access. Block the 11th thread. 
    using (SomeThreadLock lock = new SomeThreadLock(10)) 
    {   
     DoUsefulThings(args.foo); 
    } 
} 

Tôi không có quyền kiểm soát lớp khác MyObj, vì vậy tôi không thể thực hiện một luồng ở đó.

Cách tốt nhất để thực hiện điều này là gì?

Cảm ơn, PaulH

Trả lời

21

Bạn muốn Semaphore class. Đó là, trong ngắn hạn, một khóa mà chỉ cho phép một số quy định của người gọi thông qua bất cứ lúc nào.

Vì bạn không kiểm soát việc tạo chuỗi, bạn cần phải cẩn thận về các tình huống bế tắc. Các semaphores không reentrancy-aware- nếu một chuỗi đã cho nhập một semaphore nhiều lần, nó sẽ mất nhiều hơn một slot. Vì vậy, nếu mỗi chủ đề của người gọi của bạn nhập vào semaphore của bạn nhiều hơn một lần, có khả năng một bế tắc.

3

Đó là phong tục để sử dụng semaphore cho việc này. Khởi tạo nó thành 10 đơn vị. chờ() cho một đơn vị trước khi DoUsefulThings(), tín hiệu() một đơn vị sau đó.

9

Sử dụng Semaphore cho việc này. Các tham số của hàm tạo là một chút khó hiểu đối với các tham số vừa được đưa vào lớp. Tham số đầu tiên chỉ định số lượng chủ đề ban đầu được phép thông qua ngay bây giờ. Tham số thứ hai chỉ định số lượng chủ đề tối đa được phép thông qua tại bất kỳ thời điểm nào.

myobj.SomeEvent += OnSomeEvent; 
Semaphore semaphore = new Semaphore(10, 10); 

private void OnSomeEvent(object sender, MyEventArgs args) 
{ 
    semaphore.WaitOne(); 
    try 
    { 
    DoUsefulThings(args.foo); 
    } 
    finally 
    { 
    semaphore.Release(); 
    } 
} 
+1

1 để lưu ý rằng bạn nên thoát khỏi semaphore trong khối 'cuối cùng 'của try/catch. Đây là điều quan trọng - trong trường hợp mã của bạn ném một ngoại lệ, bạn muốn chắc chắn rằng semaphore được thoát. –

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