2010-02-14 26 views
33

Tôi có một số thành phần COM mà tôi gọi từ một số C# dll.Đối tượng COM đã được tách khỏi RCW cơ bản của nó không thể được sử dụng

Tôi cũng có ứng dụng winforms sử dụng .dll đó.

Khi tôi đóng ứng dụng tôi nhận được ngoại lệ này:

COM đối tượng đã được tách ra từ RCW cơ bản của nó không thể được sử dụng .

Theo dõi ngăn xếp hiển thị ngoại lệ này xuất phát từ trình phá hủy trong .dll. Tôi đã thực hiện destructor này để gọi một số phương thức dọn dẹp trong COM.

Tại sao điều này lại xảy ra? Làm thế nào là tốt nhất để giải quyết nó?

+5

Đọc: http://jake.ginnivan.net/vsto-com-interop –

+0

Có thể trùng lặp [đối tượng COM đã được tách khỏi RCW cơ bản của nó không thể sử dụng được] (http://stackoverflow.com/câu hỏi/1567017/com-đối tượng-đó-đã-được-tách ra từ-nó-cơ bản-rcw-không thể được sử dụng) – bluish

Trả lời

30

Vấn đề này được mô tả ở đây:

Is it safe to call an RCW from a finalizer?

và ở đây:

Release Excel Object In My Destructor

Vấn đề là không phải chỉ là thời gian khi nào thì các đối tượng này là để là rác được thu thập không chắc chắn, nhưng thứ tự mà trong đó finalizers được gọi cũng là nondetermin istic. Trong trường hợp này, Trình bao bọc cuộc gọi có thể gọi là Marshal.FinalReleaseComObject, có kết quả là giảm số lượng tham chiếu trên mặt COM của hàng rào sao cho đối tượng COM này có thể được giải phóng. Nhưng vì thứ tự mà trong đó finalizers được gọi là không chắc chắn, rất có thể là finalizers cho các đối tượng COM mà tham chiếu đối tượng của bạn sẽ bắn trước khi finalizer cho đối tượng của bạn. Vì vậy, mã bên trong trình phân tích của bạn đôi khi có thể hoạt động, nhưng hầu hết thời gian, một hoặc nhiều Trình bao bọc có thể gọi thời gian của bạn sẽ có số đã được gọi là finalizers và đối tượng COM cơ bản sẽ là finalizer của bạn được thực thi mã của nó.

+73

Tôi đã không làm theo một điều! : x – nawfal

+7

Nó khá rõ ràng: các wrapper COM xung quanh đối tượng bạn instantiated có thể được làm sạch trước khi bạn nhận được xung quanh để làm sạch nó lên chính mình. Bản dịch: Nếu Dispose() của bạn cố gắng gọi Marshal.ReleaseCOMObject (x) khi x nằm ngoài phạm vi đó, Dispose() của bạn sẽ thất bại. Phải kiểm tra phạm vi/vòng đời đó. Cảm ơn các liên kết tốt, @Ran. – JMD

+0

Cảm ơn nhận xét của bạn JMD, thực sự đã xóa nó cho tôi – Alex

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