2009-12-15 31 views
7

Bất kỳ ý tưởng nào tại sao mã sau không thoát khỏi quá trình Outlook 2007 được tạo thông qua COM interop?C# Outlook 2007 COM interop ứng dụng không thoát!

Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application(); 

var item = app.Session.OpenSharedItem("C:\\test.msg") as Microsoft.Office.Interop.Outlook.MailItem; 
string body = item.HTMLBody; 
int att = item.Attachments.Count; 

(item as Microsoft.Office.Interop.Outlook._MailItem).Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard); 
System.Runtime.InteropServices.Marshal.ReleaseComObject(item); 

(app as Microsoft.Office.Interop.Outlook._Application).Quit(); 
System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 
System.Diagnostics.Debugger.Break(); 

Một đoạn gần như giống hệt sử dụng Word làm việc, vì vậy tôi tự hỏi, nếu tôi quên để làm sạch một cái gì đó ...

Trả lời

10

Bạn có một đối tượng COM thứ 3 tham chiếu trong mã của bạn: app.Session. Điều này cũng phải được phát hành chính xác. Hãy thử mã này:

Microsoft.Office.Interop.Outlook.Application app = null; 
Microsoft.Office.Interop.Outlook.NameSpace session = null; 
Microsoft.Office.Interop.Outlook.MailItem item = null; 

try { 
    app = new Microsoft.Office.Interop.Outlook.Application(); 
    session = app.Session; 
    item = session.OpenSharedItem("C:\\test.msg") as Microsoft.Office.Interop.Outlook.MailItem; 

    string body = item.HTMLBody; 
    int att = item.Attachments.Count; 

    (item as Microsoft.Office.Interop.Outlook._MailItem).Close(Microsoft.Office.Interop.Outlook.OlInspectorClose.olDiscard); 

    (app as Microsoft.Office.Interop.Outlook._Application).Quit(); 
} finally { 
    if(item != null) { 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(item); 
    } 
    if(session != null) { 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(session); 
    } 
    if(app != null) { 
     System.Runtime.InteropServices.Marshal.FinalReleaseComObject(app); 
    } 
} 
+0

Điều đó có hiệu quả. Session là một đối tượng NameSpace. Cảm ơn :) – Nikolaos

+0

Không sao cả. Tôi đã thay thế tên lớp đó trong mã. –

0

Hãy thử sau đây sau khi app.Quit();

// ReleaseComObject(xApp); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
+0

Tuy kéo dài có ... Thanks anyway. – Nikolaos

+2

Sai đường xung quanh. Thu thập() phải là đầu tiên. –

+0

@nobugz: Cùng một kết quả. Quá trình vẫn còn đó sau khi Quit(). – Nikolaos

0

Hãy thử điều này thay vào đó, nó làm việc cho tôi, sẽ có một vài giây chậm trễ trước khi nó đi:

app.Quit(); // 
System.Runtime.InteropServices.Marshal.ReleaseComObject(app); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
2

Tôi không biết chi tiết cụ thể của Office COM Interops, nhưng đây là một số mã được đề xuất từ ​​MSDN article. Nó cho thấy việc thu thập/chờ đợi và thanh toán bù trừ của các con trỏ giúp với dọn dẹp wrapper RCW.

item = null; 
app.Quit(); 
app = null; 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 
GC.Collect(); 
GC.WaitForPendingFinalizers(); 

Đó url tuy nhiên cũng cho thấy

while (Marshal.ReleaseComObject(app) > 0) { } 

mà cá nhân tôi sẽ tư vấn cho mạnh mẽ chống lại nếu bạn có thể giúp nó, như bạn đã cơ bản chỉ là phá hủy mà RCW cho AppDomain của bạn (như bài báo chỉ ra).

[Edit: Ngoài ra các bộ thu rác Net cư xử rất khác nhau khi bên trong một trình gỡ lỗi vs phát hành mã, vì vậy thử nghiệm bên ngoài này của debugger là rất quan trọng]

+2

+1 cho đề xuất thu thập kép và cảnh báo gỡ lỗi. – Nikolaos

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