2008-09-22 36 views
5

Trong Visual Studio, khi tôi gõ dòng "Implements IDisposable", IDE sẽ tự động thêm:VB.NET - Một phương thức hoàn thiện có nên được bổ sung khi triển khai IDisposable không?

  • một biến disposedValue viên
  • một Sub Dispose() Implements IDisposable.Dispose
  • một Sub Dispose(ByVal disposing As Boolean)

Các Dispose() nên còn lại một mình, và mã làm sạch nên được đặt trong Dispose(disposing).

Tuy nhiên, Dispose Finalize Pattern cho biết bạn cũng nên ghi đè Sub Finalize() để gọi Dispose(False). Tại sao IDE cũng không thêm điều này? Tôi có phải tự thêm vào nó, hoặc bằng cách nào đó được gọi là ngầm?

EDIT: Bất kỳ ý tưởng nào tại sao IDE tự động thêm 80% nội dung yêu cầu nhưng bỏ qua phương thức Hoàn tất? Không phải là toàn bộ điểm của loại tính năng này để giúp bạn không phải quên những điều này?

EDIT2: Cảm ơn tất cả các câu trả lời tuyệt vời của bạn, điều này giờ đây có ý nghĩa hoàn hảo!

Trả lời

11

Nếu bạn thực sự đang nắm giữ các tài nguyên không được quản lý sẽ không được dọn dẹp tự động bởi bộ thu gom rác và làm sạch chúng trong Dispose(), thì có, bạn nên làm tương tự trong Finalize().

Nếu bạn đang triển khai IDisposable cho một số lý do khác, việc triển khai Finalize() là không bắt buộc.

Câu hỏi cơ bản là: Nếu Dispose() không được gọi và rác của đối tượng của bạn được thu thập, bộ nhớ có bị rò rỉ không? Nếu có, hãy triển khai Finalize. Nếu không, bạn không cần. Ngoài ra, tránh triển khai Finalize "chỉ vì nó an toàn hơn". Đối tượng với finalizers tùy chỉnh có thể có khả năng cần hai GC pass để giải phóng chúng - một lần để đưa chúng vào hàng đợi finalizers đang chờ xử lý, và một pass thứ hai để thực sự giải phóng bộ nhớ của chúng.

+1

Thực hiện Vứt bỏ không có nghĩa là bạn cũng nên triển khai trình kết thúc. Bạn có thể giải phóng tài nguyên không được quản lý trong một phương thức Vứt bỏ mà không cần đến trình hoàn thiện. Nếu bạn phải thực hiện một finalizer, logic dọn dẹp thực tế của bạn phải ở trong một chức năng riêng biệt mà cả hai xử lý và hoàn thành cuộc gọi. –

+1

Không chính xác.Nếu bạn chỉ dựa vào Dispose() để giải phóng tài nguyên không được quản lý, thì bộ nhớ sẽ bị rò rỉ trong trường hợp Dispose không được gọi. Đó là chính xác những gì finalizer là có cho. – Laurent

+1

Không chắc tại sao tôi không trả lời nhận xét của Scott trước đó - không được để ý, nhưng Laurent nói đúng - nếu Dispose của bạn dọn dẹp tài nguyên không được quản lý, cần phải có Finalize để đảm bảo an toàn. Đừng bỏ nó đi vì bạn lười biếng. –

3

Không, bạn không cần phải Hoàn thành trừ khi bạn có tài nguyên không được quản lý để dọn dẹp.

Trong hầu hết các trường hợp, lý do lớp là dùng một lần vì nó giữ tham chiếu đến các đối tượng IDisposable được quản lý khác. Trong trường hợp này không có phương pháp Finalize là cần thiết hoặc mong muốn.

+0

Bạn có thể giải phóng tài nguyên không được quản lý trong một phương thức Vứt bỏ mà không cần đến trình hoàn thiện. –

+0

Bạn có thể, nhưng nếu Vứt bỏ không được gọi là sau đó bạn có thể sẽ bị rò rỉ bộ nhớ mà không có một phương pháp Finalize là tốt. –

1

Như những người khác đã nói, bạn không cần phải triển khai trình kết thúc trừ khi bạn đang trực tiếp nắm giữ các tài nguyên không được quản lý. Ngoài ra, giả sử bạn đang làm việc trong .NET 2.0 hoặc mới hơn, bạn sẽ không bao giờ cần phải triển khai finalizer vì thường SafeHandle có thể được sử dụng để bọc tài nguyên không được quản lý của bạn.

Tôi đã viết fairly long blog post bao gồm nền và triển khai IDisposable và finalizers một thời gian trở lại, có thể đáng để đọc nếu bạn không hoàn toàn rõ ràng về nó.

+0

Bạn có thể giải phóng tài nguyên không được quản lý trong một phương thức Vứt bỏ mà không cần đến trình hoàn thiện. –

+0

Vâng vâng, đó là toàn bộ điểm của mẫu IDisposable. Tuy nhiên, nếu mọi người quên gọi Dispose thì finalizer là một biện pháp bảo vệ để dọn dẹp chúng cuối cùng, mà không thể quên được bởi vì nó được gọi bởi thời gian chạy. –

2
Implements IDisposable 

Public Overloads Sub Dispose() Implements IDisposable.Dispose 

    Dispose(True) 
    GC.SuppressFinalize(Me) 

End Sub 

Protected Overloads Sub Dispose(ByVal disposing As Boolean) 

    If disposing Then 
     ' Free other state (managed objects). 
    End If 
    ' Free your own state (unmanaged objects). 
    ' Set large fields to null. 
End Sub 

Protected Overrides Sub Finalize() 

    Dispose(False) 
    MyBase.Finalize() 

End Sub 
+3

Một đoạn mã không phải là rất hữu ích. Cố gắng xây dựng hơn, với một mô tả nhỏ và lý do đằng sau mã được cung cấp. –

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