我有一个Outlook AddIn,我正在加载单独的AppDomain。然后我将Outlook(COM RCW)对象传递到这些AppDomains中。这项工作的基础很好,但是当我从AppDomain中获取另一个对象引用时,引用计数似乎无法解决。
对于一个直截了当的例子,我在Mail.Compose功能区上有一个按钮,带有一个点击处理程序。此代码在主Outlook加载项AppDomain中执行。
var execAsm = System.Reflection.Assembly.GetExecutingAssembly();
var loadUri = new Uri(execAsm.CodeBase);
string loadDir = System.IO.Path.GetDirectoryName(loadUri.LocalPath);
// Create app-domain
AppDomainSetup appSetup = new AppDomainSetup();
appSetup.ApplicationBase = loadDir;
System.Security.PermissionSet permSet =
new System.Security.PermissionSet(
System.Security.Permissions.PermissionState.Unrestricted);
var myDomain = AppDomain.CreateDomain("MyDomain", null, appSetup, permSet, null);
// Get instance from app-domain
dynamic addInPoint = myDomain.CreateInstanceAndUnwrap(
assemblyName: "ClassLibrary1",
typeName: "ClassLibrary1.Class1");
// Do work on mail item
Outlook.MailItem currentMail =
Outlook.MailItem)Globals.ThisAddIn.Application.ActiveInspector()
.CurrentItem;
addInPoint.DoWork(currentMail);
// Clean-up
Marshal.ReleaseComObject(currentMail);
currentMail = null;
以下Class
实施。为了清楚起见,这只能在一个单独的AppDomain中执行。
public void DoWork(Outlook.MailItem mail)
{
mail.Save();
mail.To = "foobar@test.com";
var propAccessor = mail.PropertyAccessor;
Marshal.ReleaseComObject(propAccessor);
propAccessor = null;
}
使用场景很简单:
问题似乎在于对mail.PropertyAccessor
和后续ReleaseComObject
的调用。这个应该释放引用,并且从ReleaseComObject
返回的引用计数为零,但显然仍有引用,因为从{{1中删除了这些行方法导致在步骤4中没有“未保存的更改”提示。对于它的价值,向上移动到更强大的DoWork
方法没有任何区别。
Marshal.FinalReleaseComObject
代码也没有任何内在错误。将其移出mail.PropertyAccessor
方法,然后进入功能区按钮单击事件处理程序,正如人们所预料的那样,在步骤4中没有未保存的更改提示。
这里发生了什么?
它似乎也会在单独的AppDomain中访问访问属性。 DoWork
导致问题,但PropertyAccessor
没有。 Recipients
,Session
和Application
也都可以。实际上到目前为止,我发现麻烦的唯一MailItem属性是Attachments
。