2010-11-11 27 views
22

Lớp StreamReader có cả phương thức đóng và hủy. Tôi muốn biết phương pháp nào cần gọi để dọn sạch mọi tài nguyên.đóng hoặc hủy

Nếu sử dụng khối, tôi nghĩ nó sẽ gọi phương thức vứt bỏ của nó. Nó sẽ là đủ để làm sạch tất cả các nguồn lực.

+1

http://stackoverflow.com/q/61092/102112 – Alex

Trả lời

22

Khối using sẽ gọi Dispose() trên ví dụ StreamReader. Nói chung, nếu một loại là IDisposable, bạn nên đặt nó trong phạm vi using.

EDIT: Nếu bạn nhìn vào việc thực hiện Close() của StreamReader sử dụng Reflector, bạn sẽ thấy rằng nó đang gọi Dispose(true). Vì vậy, nếu bạn không sử dụng phạm vi using, hãy gọi Close() theo cách thủ công sẽ giống như gọi số Dispose() trong trường hợp cụ thể này.

protected override void Dispose(bool disposing) 
{ 
    try 
    { 
     if ((this.Closable && disposing) && (this.stream != null)) 
     { 
      this.stream.Close(); 
     } 
    } 
    finally 
    { 
     if (this.Closable && (this.stream != null)) 
     { 
      this.stream = null; 
      this.encoding = null; 
      this.decoder = null; 
      this.byteBuffer = null; 
      this.charBuffer = null; 
      this.charPos = 0; 
      this.charLen = 0; 
      base.Dispose(disposing); 
     } 
    } 
} 
+0

các cuộc gọi đóng vứt bỏ (đúng), sẽ sử dụng khối cũng gọi là vứt bỏ (đúng)? – user496949

+0

Yup, nó sẽ ... –

+0

Điều này giải thích tại sao nếu bạn có mã bên trong 'using' với lệnh gọi' Close() ', khi chạy Phân tích Mã của Visual Studio, bạn sẽ nhận được' CA2202 \t Không vứt bỏ đối tượng nhiều lần' - bởi vì 'Close()' đã được xử lý, và 'using' cuối cùng sẽ cố gắng xử lý đối tượng, một lần nữa. Tôi tự hỏi, sau đó ... tại sao chúng ta không thực sự đối mặt với 'System.ObjectDisposedException'. – Veverke

1

Khối sử dụng là tất cả những gì bạn cần.

+0

Việc sử dụng sẽ đảm bảo sẽ được xử lý. Nó giống như gọi điện thoại gần? – user496949

+0

vứt bỏ sẽ ngầm đóng luồng –

16

Vứt bỏ là đủ và là điều cần thiết, vì nó sẽ tự động gọi Đóng và thực hiện thêm nhiều thứ mà Close sẽ không thực hiện.

Sử dụng khối là cách thanh lịch để vứt bỏ để có, hãy sử dụng nó bất cứ khi nào có thể.

+0

Đó không phải là cách khác xung quanh, tức là. đóng sẽ gọi vứt bỏ? –

+0

@Backwards_Dave không, đó sẽ là một lỗi nghiêm trọng đối với một đối tượng để xử lý chính nó. Bạn có thể vẫn muốn sử dụng cá thể sau khi đóng nó. –

+3

Trong lớp TextReader (cha của StreamReader), việc thực hiện các phương thức 'Close()' và 'Dispose()' giống hệt nhau và gọi 'Dispose (true)'. Trong lớp StreamReader, 'Close()' gọi hàm được ghi đè là 'Dispose (true)' để phân phối đối tượng. Vì vậy, trong trường hợp này, nó là chính xác để nói rằng 'Close' gọi' Dispose'. –

0

Nếu bạn muốn biết thêm thông tin về using, hãy xem đây

Using

Trích từ trang web:

Báo cáo sử dụng cho phép các lập trình viên để xác định khi đối tượng sử dụng tài nguyên nên phát hành chúng. Đối tượng được cung cấp cho câu lệnh phải triển khai giao diện IDisposable. Giao diện này cung cấp phương thức Vứt bỏ, trong đó sẽ giải phóng tài nguyên của đối tượng.

0

Dường như có một số lo ngại về việc liệu Dispose có thực sự hoạt động đúng cách không.

Về cơ bản - bạn có thể khá chắc chắn rằng bất cứ điều gì trong BCL (Class Library Base) mà thực hiện IDisposable sẽ dọn dẹp bản thân đúng cách khi dispose được gọi - chẳng hạn như khi một tuyên bố sử dụng đi ra khỏi phạm vi.

Nếu có vấn đề với các luồng không bị đóng, chúng sẽ được chọn ngay bây giờ - bạn có thể tin tưởng IDisposable. Đó là khi bạn đang sử dụng các thư viện khác mà bạn dựa vào triển khai Dispose.

1

Sử dụng Vứt bỏ qua khối sử dụng để đảm bảo rằng việc dọn dẹp diễn ra.

Sử dụng Đóng nếu bạn hoàn thành đối tượng một cách đáng kể trước khi kết thúc khối sử dụng, để càng nhanh càng tốt trong việc phát hành bất kỳ tài nguyên nào.

Do đó, cả hai sẽ làm việc trong tay, mặc dù sau đó, hai thiết bị này có thể dư thừa nếu bạn sắp đạt đến cuối khối trong vài nano giây.

3

Chúng ta đều biết System.IO.StreamReader không phải là lớp .NET 4.0+ duy nhất triển khai IDisposable và phương thức Close(). Đối với trường hợp của StreamReader trong câu hỏi này, mã nguồn cho thấy rằng lớp cơ sở TextReader.Close(), TextReader.Dispose() cả hai đều chạy cùng một dòng mã. Bạn cũng có thể thấy trong mã rằng TextReader.Dispose() là cách triển khai khi bạn gọi StreamReader.Dispose() (vì StreamReader không ghi đè chữ ký quá tải phương thức đó là Dispose).

Vì vậy, một cuộc gọi đến StreamReader.Dispose() sẽ chạy this inherited line of code, gọi phương thức ghi đè được bảo vệ StreamReader.Dispose(disposing: true) và như vậy sẽ StreamReader.Close() gọi StreamReader.Dispose(disposing: true). Vì vậy, đối với trường hợp của StreamReader, Close()Dispose() xảy ra để chạy cùng một dòng mã.

Câu trả lời chung chung hơn, không dành riêng cho câu hỏi là Close() hoặc Dispose()?, có thể cần lưu ý rằng Microsoft có khá rõ ràng documentation on implementing IDisposable and the Dispose pattern. Đọc nhanh là đủ để cho bạn thấy rằng việc triển khai phương thức Close() không phải là yêu cầu của mẫu Xử lý.

imho lý do để tìm phương thức Close() trên nhiều lớp thực hiện IDisposable, là kết quả của quy ước, không bắt buộc.

Có người nhận xét

Close and Dispose - which to call?

Một ví dụ về một lớp mà thực hiện IDisposable với mô hình Vứt bỏ, và có một phương pháp Close(). Close() có chạy mã giống như Dispose() trong trường hợp này không? Tôi đã không nhìn vào mã nguồn, nhưng tôi muốn nói không nhất thiết.

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