2008-09-05 13 views
9

Tôi có một tình huống mà tôi có thể có nhiều phiên bản của một chương trình đang chạy cùng một lúc và điều quan trọng là chỉ một hàm cụ thể không được thực hiện trong nhiều trường hợp cùng một lúc.Đây có phải là cách sử dụng đúng đắn của một mutex không?

Đây có phải là cách thích hợp để sử dụng mutex để ngăn điều này xảy ra không?

lock (this.GetType()) { 
    _log.Info("Doing Sync"); 
    DoSync(); 
    _log.Info("Sync Completed"); 
} 

Trả lời

18

Bạn đã nói nhiều phiên bản của một ứng dụng, vì vậy chúng tôi đang nói về hai chương trình đang chạy, phải không? Tuyên bố khóa sẽ không khóa trên nhiều chương trình, chỉ trong chương trình. Nếu bạn muốn có một Mutex đúng, hãy nhìn vào đối tượng System.Threading.Mutex.

Đây là một ví dụ sử dụng:

bool createdNew; 
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew)) 
{ 
    try 
    { 
     mtx.WaitOne(); 

     MessageBox.Show("Click OK to release the mutex."); 
    } 
    finally 
    { 
     mtx.ReleaseMutex(); 
    } 
} 

Biến createdNew sẽ cho bạn biết có hay không nó đã được tạo ra lần đầu tiên. Nó chỉ cho bạn biết nếu nó đã được tạo ra, mặc dù. Nếu bạn muốn lấy khóa, bạn cần gọi WaitOne và sau đó gọi ReleaseMutex để giải phóng nó. Nếu bạn chỉ muốn xem liệu bạn có tạo ra một Mutex hay không, chỉ cần xây dựng nó là tốt.

5

TheSeeker là chính xác.

Lời khuyên của Jeff Richter trong Clr Via C# (p638-9) về khóa là tạo đối tượng riêng cho mục đích bị khóa.

private Object _lock = new Object(); 

// usage 
lock(_lock) 
{ 
    // thread-safe code here.. 
} 

Điều này hoạt động vì _lock không thể bị khóa bởi bất kỳ thứ gì ngoài lớp hiện tại.

CHỈNH SỬA: điều này có thể áp dụng cho các chuỗi thực hiện trong một quy trình. Câu trả lời của @David Mohundro là chính xác cho khóa liên ngành.