为什么以下代码不会退出通过COM interop创建的Outlook 2007进程的任何想法?
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();
使用Word的几乎完全相同的代码段,所以我想知道我是否忘记清理某些内容......
答案 0 :(得分:10)
您的代码中引用了第3个COM对象:app.Session
。这也必须正确发布。试试这段代码:
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);
}
}
答案 1 :(得分:2)
我不知道Office COM Interops的具体细节,但这里有一些代码来自MSDN article。它建议双重收集/等待和清除指针有助于RCW包装器清理。
item = null;
app.Quit();
app = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
GC.WaitForPendingFinalizers();
然而,该网址也暗示
while (Marshal.ReleaseComObject(app) > 0) { }
如果你能提供帮助,我个人会强烈反对,因为你基本上只是为你的AppDomain销毁了RCW(正如文章指出的那样)。
[编辑:在调试器和发布代码中,.Net垃圾收集器的行为也非常不同,因此在调试器外部进行测试非常重要]
答案 2 :(得分:0)
在app.Quit();
之后尝试关注// ReleaseComObject(xApp);
GC.WaitForPendingFinalizers();
GC.Collect();
答案 3 :(得分:0)
试试这个,它适用于我,在它之前会有几秒钟的延迟:
app.Quit(); //
System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
GC.Collect();
GC.WaitForPendingFinalizers();