2011-12-19 65 views

Trả lời

7

Điểm của cả hai cấu trúc này là ngăn chặn bộ thu gom rác giải phóng tài nguyên và vô hiệu hóa tay cầm trước khi cuộc gọi P/Invoke kết thúc. Tài liệu bạn đã liên kết cho biết rằng đây là những loại đặc biệt được nhận dạng bởi trình sửa đổi nội dung.

Điều tôi thu thập từ tài liệu là HandleRef về cơ bản là trường hợp đặc biệt của cấu trúc tổng quát hơn GCHandle.

Cấu trúc HandleRef được thiết kế đặc biệt để gói các chốt xử lý vào các tài nguyên không được quản lý được sử dụng với mã P/Invoke. Ví dụ: tay cầm cửa sổ (HWND) hoặc ngữ cảnh của thiết bị (HDC). Nó có thuộc tính Handle trả về giá trị loại IntPtr, là giá trị số nguyên kích thước của con trỏ trên kiến ​​trúc của hệ thống bên dưới. Bạn có thể sử dụng điều này để nhanh chóng & dễ dàng có được xử lý nó kết thúc tốt đẹp.

Trong khi cấu trúc GCHandle cho phép một để xác định loại tay cầm nó kết thúc tốt đẹp bằng một trong những thành viên của GCHandleType liệt kê, cấu trúc HandleRef được thiết kế đặc biệt để quấn tay cầm với các nguồn lực không được quản lý. Bạn có thể sử dụng cấu trúc GCHandle khi bạn đang xử lý trực tiếp với bộ nhớ không được quản lý, thay vì các xử lý đặc biệt mà API Win32 xử lý như các hộp đen.

Không cần thiết phải sử dụng một trong hai. Người ta có thể chỉ cần gọi GC.KeepAlive để giữ cho bộ thu gom rác khỏi phát hành sớm tài nguyên.

Và thậm chí điều đó có lẽ không cần thiết. Tôi đã viết P/Invoke mã trong nhiều năm, và tôi đã tìm thấy rằng khi nó được viết chính xác, không cần thiết cho một trong các cấu trúc này. Nếu một đối tượng lớp bị thu thập rác trong khi cuộc gọi API đang ở giữa thực thi, thì đó là một lỗi trong ứng dụng của bạn. Tôi thực sự muốn để được thông báo về sự cố thông qua ngoại lệ, không ẩn nó.

+0

Cảm ơn bạn đã trả lời –

+1

"Tôi đã tìm thấy rằng khi nó được viết chính xác, không cần thiết cho một trong các cấu trúc này." Điều gì sẽ xảy ra nếu bạn không lo lắng về việc giữ cho đối tượng không được thu thập vì bạn biết mã được quản lý sẽ tiếp tục tham chiếu, nhưng bạn chỉ muốn mã không được quản lý để chấp nhận/giữ/trả về các tham chiếu được quản lý vì lý do nào đó. Ví dụ: stackoverflow .com/questions/32105089 –

0

Một sự khác biệt được đưa ra trong link bạn đề cập:

Các HandleRef kiểu giá trị, như GCHandle, là một loại đặc biệt công nhận bởi người so sánh interop. Một GCHandle bình thường, không được gõ cũng ngăn không cho thu gom rác không đúng lúc , nhưng HandleRef cung cấp hiệu suất tốt hơn . Mặc dù sử dụng HandleRef để giữ một đối tượng còn sống cho thời lượng của một cuộc gọi nền tảng gọi được ưu tiên, bạn cũng có thể sử dụng phương thức GC.KeepAlive GC cho cùng một mục đích.

+0

Có, tôi thấy điều đó, nhưng tôi cần thông tin chi tiết –

+1

@user: Bạn muốn biết thêm thông tin chi tiết nào? –

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