2011-08-22 29 views
5

Ứng dụng của tôi là sự kết hợp của mã C# và C++. Mô-đun khởi động được viết bằng tải C# trong quá trình khởi tạo giai đoạn C++ mô-đun thông qua cơ chế COM (Component Object Model). Tất cả đều hoạt động chính xác cho đến khi tôi quyết định thêm vào C# một phần dịch vụ wcf. Tất cả các cuộc gọi dịch vụ wcf được định tuyến đến mã C++ bằng cách sử dụng COM. Sau khi thêm một số phương pháp mới, tôi nhận thấy rò rỉ bộ nhớ trong cửa sổ đầu ra. Vì vậy, tôi thêm breakpoint để desctructor của lớp C++ như có thể được nhìn thấy từ ảnh chụp màn hình. Từ thời điểm này, những điều kì lạ bắt đầu xảy ra. Sau khi chương trình đạt đến điểm ngắt nó bất ngờ gặp sự cố. Điều kỳ lạ đầu tiên là khi tôi chạy chương trình mà không có breakpoint được thiết lập nó kết thúc ân cần. Điều kỳ lạ thứ hai là cách chương trình bị treo như thể nó đang chạy mà không có trình gỡ rối. Sau khi nhấp vào nút "Open in debugger" (hoặc một cái gì đó như thế này) tôi nhận được thông báo lỗi: "Chương trình đã được mở theo trình gỡ rối." Không có thông báo nào trong cửa sổ đầu ra có thể dẫn tôi đến nguồn của lỗi, không có mã đáng ngờ nào. Khi thêm hộp thông báo vào trình phá hủy bắt đầu, nó hiển thị phần nhỏ của giây và sau đó toàn bộ ứng dụng đóng (không thêm cơ hội người dùng để đọc những gì được hiển thị trong hộp tin nhắn). Tìm kiếm tuyệt đối cho bất kỳ đầu mối nào.Tai nạn lạ khi gỡ lỗi đối tượng COM destructor

P.S. Vấn đề chỉ xảy ra khi phương pháp wcf được gọi ít nhất một lần. Không phụ thuộc nếu luồng chương trình trong cuộc gọi cụ thể này được chuyển đến cấp độ C++ hay không.

enter image description here

enter image description here

+0

Hãy thử sử dụng WinDbg thay vì trình gỡ lỗi VS để biết thêm thông tin về sự cố – SpaceghostAli

Trả lời

0

giải quyết bằng mã sau:

public void Dispose() 
{ 
    Marshal.Release(internal_interface_ptr); 
    internal_interface_ptr = IntPtr.Zero; 
    Marshal.ReleaseComObject(internal_interface); 
    Marshal.ReleaseComObject(internal_interface); 
    internal_interface = null; 
} 

Bên cạnh một tài liệu tham khảo khác này được treo trong C++. Vì vậy, để đưa ra kết luận, sai lầm chính trên một phần của tôi đã quên để phát hành rõ ràng đối tượng COM trong mã C#. Ngay cả khi bộ thu gom rác có nhiệm vụ quản lý bộ nhớ thì điều này không đúng đối với các mô-đun được viết bằng các ngôn ngữ lập trình khác. COM destructor được gọi là rất gần đây khi thư viện liên kết động cụ thể đã được giải phóng khỏi bộ nhớ và điều này gây ra vấn đề. Hy vọng tôi đã giải thích nó đủ rõ ràng.

1

Khi gọi C# từ C++ đôi khi thu gom rác không đúng cách có được gọi là trước khi kết thúc chương trình. Hãy thử buộc thu gom rác ở cuối mã C# của bạn.

+0

Đâm như thể phép màu biến mất, tuy nhiên chương trình kết thúc trước khi tất cả các trình phá hủy COM hoàn thành công việc của họ. Xem ảnh chụp màn hình thứ hai của tôi. Tại thời điểm chính xác chương trình này là ngay trước khi kết thúc của nó, nhưng một số destructors COM werent gọi được nêu ra. Sau khi họ được gọi là công việc của họ được hoàn thành đột ngột. – truthseeker

+0

Được giải quyết bằng mã sau: khoảng trống công khai Vứt bỏ() { Marshal.Release (internal_interface_ptr); internal_interface_ptr = IntPtr.Zero; Marshal.ReleaseComObject (internal_interface); internal_interface = null; } – truthseeker

+0

Tôi không hoàn toàn chắc chắn ý bạn là gì bởi "Đâm vỡ như thể phép lạ biến mất". Tôi nghĩ rằng bạn có thể cần phải buộc các dịch vụ của bạn phải vứt bỏ trước khi gọi cho người thu thập garbase. Kiểm tra để đảm bảo hoặc ServiceToRun hoặc dịch vụ được xử lý trước khi bộ sưu tập garbase chạy nếu không chạy sẽ làm bạn không tốt. – mydogisbox

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