2009-03-13 26 views
8

Đây có phải là quá mức cần thiết và chỉ một trong những điều này cần thiết không? Tôi đã tìm kiếm và tìm thấy các bài đăng khác nhau về Loại trừ lẫn nhau và khóa trong C# herehere.

Ví dụ:
Trong ứng dụng của chúng tôi, chúng tôi có chức năng xoay nhiều chuỗi kết nối lại và bên trong chuỗi này, chúng tôi sử dụng Mutexlock. Sẽ không lock chặn truy cập vào phần mã này và ngăn không cho connect cập nhật bởi bất kỳ chủ đề nào khác không?Nên Khóa và Mutexes trong C# được sử dụng cùng nhau

bool connect = false; 
Mutex reconnectMutex = new Mutex(false, "Reconnect_" + key); 

try 
{ 
    lock(site) 
    { 
     if(site.ContainsKey(key)) 
     { 
     siteInfo = (SiteInfo)site[key]; 
     if(reconnectMutex.WaitOne(100, true)) 
     { 
      connect = true; 
     } 
     } 
    } 

    if (connect) 
    { 
     // Process thread logic 
    } 
} 
catch 
{} 

reconnectMutex.ReleaseMutex(); 

Thông tin thêm:
Đây là một ASP.NET WebService không chạy trong Web Garden.

Trả lời

11

Mutex đó (vì nó có tên) sẽ dừng bất kỳ quá trình nào trên cùng một máy truy cập vào nó, trong khi khóa sẽ chỉ dừng các luồng khác trong cùng một quy trình. Tôi không thể nhìn thấy từ mẫu mã đó tại sao bạn cần cả hai loại khóa. Có vẻ như thực hành tốt để giữ khóa đơn giản trong một khoảng thời gian ngắn - nhưng sau đó, mutex interprocess nặng hơn nhiều sẽ bị khóa trong thời gian dài hơn (mặc dù chồng chéo)! Sẽ đơn giản hơn khi chỉ sử dụng mutex. Và có lẽ để tìm hiểu xem một khóa interprocess là thực sự cần thiết.

Nhân tiện, catch {} hoàn toàn là điều sai để sử dụng trong trường hợp đó. Bạn nên sử dụng finally { /* release mutex */ }. Họ rất khác nhau. Việc nắm bắt sẽ nuốt nhiều loại ngoại lệ hơn cần, và cũng sẽ gây lồng cuối cùng xử lý để thực hiện để đáp ứng với trường hợp ngoại lệ ở mức độ thấp như tham nhũng bộ nhớ, vi phạm truy cập, vv Vì vậy, thay vì:

try 
{ 
    // something 
} 
catch 
{} 

// cleanup 

bạn nên có:

try 
{ 
    // something 
} 
finally 
{ 
    // cleanup 
} 

Và nếu có những ngoại lệ cụ thể mà bạn có thể phục hồi từ, bạn có thể bắt chúng:

try 
{ 
    // something 
} 
catch (DatabaseConfigurationError x) 
{ 
    // tell the user to configure the database properly 
} 
finally 
{ 
    // cleanup 
} 
+0

phải được đặt tên phù hợp để cụ thể cho máy. –

+0

Điểm tốt, tôi hy vọng làm rõ rằng trong câu đầu tiên. –

+0

Bạn đang nói tôi nên loại bỏ câu lệnh khai thác và thay thế nó bằng một cái cuối cùng? –

3

"khóa" về cơ bản chỉ là một cú pháp đường cho Montor.Enter/Exit. Mutex là một khóa đa tiến trình.

Chúng có hành vi rất khác nhau. Không có gì sai khi sử dụng cả hai trong cùng một ứng dụng hoặc các phương thức, vì chúng được thiết kế để chặn những thứ khác nhau.

Tuy nhiên, trong trường hợp của bạn, tôi nghĩ bạn có thể nên xem Semaphore và Màn hình tốt hơn. Nó không có vẻ như bạn cần phải khóa qua các quá trình, vì vậy họ có lẽ là một sự lựa chọn tốt hơn trong tình huống này.

1

Bạn không cung cấp đủ thông tin để thực sự trả lời câu hỏi này. Như đã nêu bởi Earwicker một Mutex cho phép bạn có một quá trình đồng bộ hóa. Vì vậy, nếu bạn có hai trường hợp của cùng một ứng dụng đang chạy, bạn có thể tuần tự hóa truy cập. Bạn có thể làm điều này ví dụ khi sử dụng tài nguyên bên ngoài.

Giờ đây, bạn khóa trên trang web bảo vệ trang web không bị truy cập bởi các chủ đề khác trong cùng một quy trình. Điều này có thể được nessecary tùy thuộc vào những gì các phương pháp khác/chủ đề đang làm. Bây giờ nếu đây là nơi duy nhất mà trang web đang bị khóa thì có, tôi sẽ nghĩ rằng nó là quá mức cần thiết.

2

Như những người khác đã chỉ ra, khóa Mutex trên các quy trình và khóa cục bộ (Màn hình) chỉ khóa những chủ sở hữu của quy trình hiện tại. Tuy nhiên ...

Mã bạn đã hiển thị có lỗi nghiêm trọng.Có vẻ như bạn đang phát hành Mutex một cách vô điều kiện vào cuối (ví dụ: reconnectMutex.ReleaseMutex()), nhưng Mutex chỉ được mua nếu site.ContainsKey() trả lại true.

Vì vậy, nếu site.ContainsKey trả lại false, sau đó nhả Mutex sẽ ném ApplicationException vì chuỗi cuộc gọi không sở hữu Mutex. Tuy nhiên,

+0

Cảm ơn - Tôi đã tìm thấy lỗi đó sau khi tôi đăng nội dung này. Tôi không thể tìm ra lý do tại sao các ứng dụng đã được chỉ đóng cửa - đó là vấn đề. –

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