2012-01-19 33 views
19

Khuôn khổ Microsoft.NET cung cấp giao diện IDisposable yêu cầu triển khai phương thức void Dispose(). Mục đích của nó là để cho phép hướng dẫn sử dụng, hoặc phạm vi dựa trên phát hành các nguồn lực đắt tiền thực hiện IDisposable có thể đã được phân bổ. Ví dụ bao gồm bộ sưu tập cơ sở dữ liệu, luồng và xử lý.Việc triển khai IDisposable.Dispose() có nên là idempotent không?

Câu hỏi của tôi là, việc triển khai phương pháp Dispose() là không đáng tin cậy - khi được gọi nhiều lần trong cùng một trường hợp, cá thể được 'xử lý' chỉ một lần và các cuộc gọi tiếp theo không phải để ném ngoại lệ. Trong Java, hầu hết các đối tượng có hành vi tương tự (một lần nữa các luồng và kết nối cơ sở dữ liệu đến với tâm trí của tôi làm ví dụ) là không cần thiết cho hoạt động close() của chúng, tương tự như phương thức Dispose().

Tuy nhiên, kinh nghiệm cá nhân của tôi với NET (và Windows Forms nói riêng), cho thấy rằng không phải tất cả hiện thực (nghĩa là một phần của .NET framework) là idempotent, do đó cuộc gọi tiếp theo đối với các ném một ObjectDisposedException . Điều này thực sự gây nhầm lẫn cho tôi về cách thực hiện một đối tượng dùng một lần nên được tiếp cận. Có một câu trả lời chung cho kịch bản, hoặc là nó phụ thuộc vào bối cảnh cụ thể của đối tượng và cách sử dụng của nó?

Trả lời

18

nên việc thực hiện các phương pháp Dispose() được idempotent

Vâng, nó cần. Không có nói bao nhiêu lần nó sẽ được gọi.

Từ Implementing a Dispose Method trên MSDN:

một phương thức Dispose nên callable nhiều lần mà không cần ném một ngoại lệ.

Một đối tượng có triển khai tốt IDispose sẽ có cờ trường boolean cho biết nó đã được xử lý và các cuộc gọi tiếp theo không làm gì (như đã được xử lý).

+7

Chỉ vì Microsoft không luôn tuân theo đề xuất của riêng họ không có nghĩa là bạn nên làm như vậy. – linkerro

+0

@linkerro - Bạn có thể mở rộng nhận xét khá khó hiểu của mình không? – Oded

+0

Tôi tự hỏi nếu anh ta đề cập đến WinForms ném một ngoại lệ nếu bạn Vứt bỏ một điều khiển hai lần. – DaveShaw

5

From MSDN:

Cho phép một phương thức Dispose được gọi là nhiều hơn một lần mà không cần ném một ngoại lệ. Phương pháp không nên làm gì sau cuộc gọi đầu tiên.

+3

Bạn có lẽ cần phải bao gồm điểm tiếp theo cho rõ ràng: "Ném một ObjectDisposedException từ các phương thức ví dụ trên loại này (trừ Xử lý) khi tài nguyên đã được xử lý. Quy tắc này không áp dụng cho phương thức Vứt bỏ vì nó phải được gọi nhiều lần mà không cần ném một ngoại lệ. " – Jamiec

7

Có, cũng đảm bảo các phương pháp khác của lớp phản hồi chính xác khi chúng được gọi khi đối tượng đã được xử lý.

public void SomeMethod() 
{ 
    if(_disposed) 
    { 
     throw new ObjectDisposedException(); 
    } 
    else 
    { 
     // ... 
    } 

} 
+0

Có khả năng đối phó ở đây có thể chỉ đơn giản là ném một ngoại lệ. Và tôi không thực sự chắc chắn nếu bất cứ điều gì nên được yêu cầu ở tất cả. Xin vui lòng không yêu cầu đối tượng xử lý vẫn còn "làm việc" một cách nào đó. Cố gắng sử dụng một đối tượng được xử lý là một lỗi và cần được xử lý như vậy. –

+0

@ R.MartinhoFernandes - vâng nhưng vẫn còn một cái gì đó để thêm :) –

+0

@ R.MartinhoFernandes, tôi nghĩ những gì @Emo đang nói là - nếu bạn vẫn sở hữu một tham chiếu đến một đối tượng đã được xử lý, và gọi một số phương pháp khác nó có, các phương thức này nên ném 'ObjectDisposedException', hoặc thông báo cho người gọi rằng hoạt động này là bất hợp pháp ở trạng thái này. Thật không may, tôi tin rằng điều này có thể đến với một giải thưởng về nhận thức sai lệch. –

3

Cá nhân - Có - Tôi luôn đặt Dispose() idempotent.

Trong cuộc sống bình thường-cyle của một đối tượng trong một ứng dụng nhất định nó có thể không cần thiết - cuộc sống cyle từ sáng tạo để xử lý có thể được xác định và nổi tiếng.

Tuy nhiên, bằng nhau, trong một số ứng dụng, nó có thể không rõ ràng. Ví dụ, trong một kịch bản trang trí: Tôi có thể có một đối tượng dùng một lần A, được trang trí bởi một đối tượng dùng một lần B. Tôi có thể muốn loại bỏ A một cách rõ ràng, và Vứt bỏ trên B cũng có thể vứt bỏ trường hợp nó kết thúc tốt đẹp (nghĩ: dòng).

Cho nó là tương đối dễ dàng để làm cho Dispose idempotent (tức là nếu đã được xử lý, không làm gì), có vẻ như ngớ ngẩn không.

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