2013-04-07 8 views
8

Này, nếu tôi có khối sau trên C# mã:Exceptions bên trong khối khóa

public class SynchedClass 
{ 
    public void addData(object v) 
    { 
     lock(lockObject) 
     { 
      //Shall I worry about catching an exception here? 

      //Do the work 
      //arr.Add(v); 
     } 
    } 
    private List<object> arr = new List<object>(); 
    private object lockObject = new object(); 
} 

tôi sẽ cố gắng để bắt ngoại lệ bên trong khối lock? (Mối quan tâm chính của tôi là ngoại lệ có thể được nâng lên bên trong khóa sẽ ngăn khóa không bị "mở khóa").

Trả lời

20

Khóa sẽ được giải phóng khi ngoại lệ thoát khỏi khối khóa.

Đó là bởi vì lock(){...} là dịch bởi trình biên dịch khoảng vào:

Monitor.Enter(obj); 
try{ 

// contents of the lock block 

}finally{ 
    Monitor.Exit(obj); 
} 
+0

Vì vậy, cách tôi viết nó ở trên phải là tốt, phải không? – c00000fd

+1

Nếu bạn cuối cùng bắt được ngoại lệ ở đâu đó lên ngăn xếp cuộc gọi, sau đó nó sẽ là ok. Nếu không, ứng dụng của bạn sẽ bị lỗi :) – alex

1

Một tuyên bố khóa dạng "khóa (x) ..." trong đó x là một biểu hiện của một tài liệu tham khảo-type, là chính xác tương đương với (C# 4.0):

bool entered = false; 
try { 
    System.Threading.Monitor.Enter(x, ref entered); 
    ... 
} 
finally { if (entered) System.Threading.Monitor.Exit(x); } 
1

Có nhiều điều cần xem xét hơn là chỉ phát hành mutex.

Một ngoại lệ xảy ra với một số lock sẽ giải phóng khóa, nhưng hiện tại chương trình là gì? Một chủ đề chờ đợi trên khóa bây giờ sẽ thức dậy, và có lẽ bây giờ sẽ được giao dịch với nhà nước không hợp lệ. Đây là một vấn đề khó khăn không có giải pháp lý tưởng.

Điều tốt nhất là cố gắng giữ cho ổ khóa của bạn càng nhỏ càng tốt và gọi các phương thức không được ném. (Đó là bỏ qua các elepant trong phòng đó là ác ThreadAbortException ...)

Để có một cuộc thảo luận tốt về những vấn đề này, hãy xem bài viết của Eric Lippert: Locks and exceptions do not mix.

+0

Vâng, nói dễ hơn làm. Tôi không nghĩ rằng có một phương pháp duy nhất NET. Mà không tăng một số loại ngoại lệ. – c00000fd