2009-12-28 27 views
20

Jon Skeet made a comment (via Twitter) trên SOApiDotNet mã (một thư viện .NET cho API pre-alpha Stack Overflow) của tôi:C#: "Sử dụng" Báo cáo với HttpWebRequests/HttpWebResponses

@ maximz2005 Một điều tôi đã nhận thấy chỉ cần duyệt nguồn nhanh chóng: bạn không xử lý (sic) các WebResponses. "sử dụng" báo cáo FTW.

Anh ấy chỉ ra rằng tôi cần gói các phiên web này trong câu lệnh "sử dụng". Tuy nhiên, tôi có một câu hỏi về điều này: tôi có nên bọc toàn bộ điều, bắt đầu bằng HttpWebRequest, hoặc tôi nên tạo WebRequest bên ngoài câu lệnh "đang sử dụng" và sau đó bọc Phản hồi bên trong? Tôi có cảm giác rằng sự khác biệt là ở chỗ, trước đây, cả hai vật thể sẽ được xử lý - điều này có đúng không?

Xin cảm ơn trước.

Trả lời

42

HttpWebRequest chính nó không phải là dùng một lần không giống như HttpWebResponse. Bạn nên quấn các tài nguyên dùng một lần với việc sử dụng để cho phép dọn dẹp sớm và được xác định. Việc triển khai đúng mô hình IDisposable cho phép nhiều cuộc gọi đến Dispose mà không có bất kỳ vấn đề nào vì vậy ngay cả câu lệnh bọc ngoài sử dụng câu lệnh bên ngoài mà trong quá trình xử lý riêng của nó sẽ phân phối tài nguyên khai báo sử dụng bên trong thì nó vẫn ổn.

Mã dụ

var request = (HttpWebRequest)WebRequest.Create("example.com"); 
using (var response = (HttpWebResponse)request.GetResponse()) 
{ 
    // Code here 
} 
+0

Vì vậy, tôi nên khai báo ..Yêu cầu bên ngoài hay gì? –

+2

Có, điều đó có nghĩa là bạn sẽ thực hiện một yêu cầu var = (HttpWebRequest) WebRequest.Create ("http://example.com"); sử dụng (yêu cầu var response = (HttpWebResponse).GetResponse()) { // Mã số tại đây } –

+1

@Dzmitry, @Benjamin. Tôi đã thêm ví dụ mã của Benjamin vào câu trả lời của bạn. –

6

Mọi thứ được bao bọc trong khối sử dụng() {} (nghĩa là, bên trong dấu ngoặc đầu tiên) được xử lý khi bạn rời khỏi phạm vi.

Tôi chưa sử dụng thư viện của bạn (có vẻ tốt đẹp), nhưng tôi cho rằng bạn nên loại bỏ mọi IDisposable bạn tạo một cách rõ ràng (= chịu trách nhiệm) và không quay lại người gọi.

Một sidenote, vì tôi đã nhìn thấy rất nhiều người dân đang gặp khó khăn với nhiều điều để xử lý: Thay vì

using (var foo = SomeIDisposable) { 
    using (var bar = SomeOtherIDisposable) { 
    } 
} 

mà cần rất nhiều không gian dọc bạn có thể viết

using (var foo = SomeIDisposable) 
using (var bar = SomeOtherIDisposable) { 
} 
+0

Đoạn thứ hai của bạn (đúng, tôi tin) mâu thuẫn với câu đầu tiên. Nếu tất cả mọi thứ bên trong khối sử dụng được xử lý, bạn sẽ không cần câu lệnh sử dụng bên trong. – Tomas

+0

Xem bài đăng cập nhật của tôi: Mọi thứ bên trong việc sử dụng (...) được xử lý khi bạn rời khỏi khối sau (phần này: {...}) –

1

Để ngăn chặn rò rỉ bộ nhớ, bạn nên gọi Dispose trên tất cả các đối tượng mà thực hiện IDisposable. Bạn có thể đảm bảo rằng phương thức Dispose được gọi bằng cách sử dụng từ khóa đang sử dụng (không có ý định chơi chữ) vì nó chỉ là một cú pháp cú pháp cho khối thử cuối cùng.

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