629
Chương 16: Các giao diện và mẫu thông dụng
5.
5.
Hi n th c l p kh -h y (disposable class)
ệ
ự ớ
ả ủ
Hi n th c l p kh -h y (disposable class)
ệ
ự ớ
ả ủ
Bạn cần tạo một lớp có tham chiếu đến các tài nguyên không-được-quản-lý và
cung cấp một cơ chế để người dùng giải phóng các tài nguyên đó một cách tất
định.
Hiện thực giao diện
System.IDisposable
, và giải phóng các tài nguyên không-
được-quản-lý khi mã client gọi phương thức
IDisposable.Dispose
.
Một đối tượng không được tham chiếu đến vẫn tồn tại trên vùng nhớ động (heap) và tiêu thụ
các tài nguyên cho đến khi bộ thu gom rác (Garbage Collector) giải phóng đối tượng và các
tài nguyên. Bộ thu gom rác sẽ tự động giải phóng các tài nguyên được-quản-lý (như bộ nhớ),
nhưng nó sẽ không giải phóng các tài nguyên không-được-quản-lý (như file handle và kết nối
cơ sở dữ liệu) được tham chiếu bởi các đối tượng được-quản-lý. Nếu một đối tượng chứa các
thành viên dữ liệu tham chiếu đến các tài nguyên không-được-quản-lý, đối tượng này phải
giải phóng các tài nguyên đó.
Một giải pháp là khai báo một destructor—hay finalizer—cho lớp. Trước khi giải phóng phần
bộ nhớ do một thể hiện của lớp sử dụng, bộ thu gom rác sẽ gọi finalizer của đối tượng này.
Finalizer có thể thực hiện các bước cần thiết để giải phóng các tài nguyên không-được-quản-
lý. Vì bộ thu gom rác chỉ sử dụng một tiểu trình để thực thi tất cả các finalizer, việc sử dụng
finalizer có thể bất lợi trong quá trình thu gom rác và ảnh hưởng đến hiệu năng của ứng dụng.
Ngoài ra, bạn không thể kiểm soát khi bộ thực thi giải phóng các tài nguyên không-được-
quản-lý vì bạn không thể trực tiếp gọi finalizer của một đối tượng, và bạn chỉ có quyền kiểm
soát hạn chế trên các hoạt động của bộ thu gom rác bằng lớp
System.GC
.
Bằng cách sử dụng finalizer, .NET Framework định nghĩa mẫu Dispose như một phương tiện
cung cấp quyền kiểm soát khi bộ thực thi giải phóng các tài nguyên không-được-quản-lý. Để
hiện thực mẫu Dispose, lớp phải hiện thực giao diện
IDisposable
. Giao diện này khai báo một
phương thức có tên là
Dispose
; trong đó, bạn phải hiện thực phần mã cần thiết để giải phóng
các tài nguyên không-được-quản-lý.
Các thể hiện của các lớp có hiện thực mẫu Dispose được gọi là các đối tượng khả-hủy
(disposable object). Khi mã lệnh đã hoàn tất với một đối tượng khả-hủy, nó sẽ gọi phương
thức
Dispose
của đối tượng để giải phóng các tài nguyên không-được-quản-lý, vẫn dựa vào bộ
thu gom rác để giải phóng các tài nguyên được-quản-lý của đối tượng. Cần hiểu rằng bộ thực
thi không bắt buộc hủy các đối tượng; việc gọi phương thức
Dispose
là nhiệm vụ của client.
Tuy nhiên, vì thư viện lớp .NET Framework sử dụng mẫu Dispose rộng khắp nên C# cung cấp
lệnh
using
để đơn giản hóa việc sử dụng các đối tượng khả-hủy. Đoạn mã sau trình bày cấu
trúc của lệnh
using
:
using (FileStream fileStream = new FileStream("SomeFile.txt",
FileMode.Open)) {
// Làm gì đó với đối tượng fileStream...
}
Dưới đây là một số điểm cần lưu ý khi hiện thực mẫu Dispose: