2012-02-13 42 views
5

Tôi biết điều này đã được thảo luận trước đó nhưng tôi không thể tìm thấy câu trả lời thỏa đáng.Phát hành đối tượng COM trong C#

Tôi có một tệp e-mail (.msg) mà tôi mở như sau và sau đó gọi Hiển thị.

oApp = new Microsoft.Office.Interop.Outlook.Application(); 
mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); 
mail.Display(false); 
oApp = null; // do I need to release this object ? 

người dùng có thể đóng và mở lại. Trước khi họ nhấp vào "mở lại" tôi kiểm tra xem cửa sổ vẫn còn tồn tại, nếu có .. sau đó chỉ cần gửi một SetForeground (hwnd) đến cửa sổ đó. nếu không, điều đó có nghĩa là người dùng đã đóng nó để chỉ phát hành đối tượng mailItem và mở lại.

public static void ReleaseCOMObject(Microsoft.Office.Interop.Outlook.MailItem item) { 
     int r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 
     while (r != 0) { 
      r = System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 
     } 
    } 

Nếu tôi cố gắng mở lại cùng một tệp. Nó "đôi khi" ném một "tập tin trong sử dụng ngoại lệ" Vì vậy, tôi nghĩ rằng mặc dù tôi đang phát hành MailItem .. nó không được phát hành đúng cách.

Tôi có thể làm gì để đảm bảo rằng nó được phát hành đúng cách. đóng và mở lại một tệp là một tình huống rất phổ biến.

Mọi con trỏ sẽ rất hữu ích.

+1

Bạn chỉ nên "giải phóng" khi bạn tăng bộ đếm tham chiếu, "giải phóng" các tham chiếu khác của người khác có thể gây ra sự cố. – Matthew

Trả lời

6

Nếu bạn đang sử dụng tính năng COM-interop của .NET (bạn) thì bạn không cần phải lo lắng về điều này.

COM theo dõi số lượng tham chiếu - và khi số lượng truy cập đạt 0 đối tượng COM được phát hành tự động - và .NET sẽ chăm sóc làm việc với cơ chế tính tham chiếu COM chuẩn cho bạn.

Nếu bạn là P/Gọi vào thư viện C, mọi thứ có thể khác nhau - nhưng bạn không nên có bất kỳ lo lắng nào trong trường hợp chuẩn như của bạn.

+0

Không chắc chắn những gì tôi đang làm sai. Tôi nhận thấy rằng một khi tôi nhận được "File In use Exception" khởi động lại triển vọng của tôi làm các trick. Tôi cần loại dọn dẹp nào cho "oApp = new Microsoft.Office.Interop.Outlook.Application();" ? – karephul

+2

Hoạt động của nó bây giờ -> Có một mô-đun khác đang giữ trên MailItem và không phát hành nó. – karephul

+0

BTW, chỉ muốn cho bạn biết rằng tôi vẫn phải "ReleaseCOMObject" để làm cho nó hoạt động. – karephul

3

điều Làm như thế này:

mail = (Microsoft.Office.Interop.Outlook.MailItem)oApp.Session.OpenSharedItem(fileName); 

sẽ gây ra các tài liệu tham khảo để không bị xử lý ngay cả khi bạn gọi ReleaseComObject vì tham chiếu đến đối tượng trẻ em chưa được xử lý đúng cách.

Bạn nên thực hiện các cuộc gọi như thế này:

session = oApp.Session; 
mail = (Microsoft.Office.Interop.Outlook.MailItem)session.OpenSharedItem(fileName); 

Và bạn nên vứt bỏ mỗi một trong các tiểu đối tượng, giống như phiên, đến lượt mình.

+0

Tôi nhận thấy rằng nếu triển vọng không chạy trên máy của tôi .. đóng và mở lại (cách tôi mô tả trước đó) hoạt động tốt. Tôi nghĩ rằng một số cách triển vọng đang giữ tham chiếu đến tập tin đó. Có con trỏ nào không? Tôi cũng cố gắng giải phóng đối tượng Session một cách riêng biệt (không hoạt động) – karephul

+0

Bạn có gọi cho Nguyên soái không.Phương pháp ReleaseComObject trong cùng một phương pháp mà bạn đang nhận được mục thư hoặc bạn đang làm nó trong một số xử lý sự kiện onclose hoặc một cái gì đó như thế? – Nanhydrin

+0

Trước khi người dùng có thể mở một mục thư, chúng tôi kiểm tra xem có cửa sổ có cùng tiêu đề hay không. Nếu không, sau đó ReleaseComObject (mailItem) .. và mở lại. [Người dùng có thể đã đóng cửa sổ email] .. Về cơ bản tôi giữ trên MailItem miễn là tôi có thể để tôi có thể lưu nó định kỳ. – karephul

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