我的问题是关于使用Outlook进行VSTO .NET开发。
由于在VSTO中处理.NET事件处理程序的方式,必须保持对COM对象的引用,该COM对象表示要触发的项目上的事件处理程序的项目。这是通过声明一个类级变量来完成的,该变量将使引用不被垃圾收集。
我的插件正在处理日历,联系人和任务的BeforeDelete事件。
我担心保留List对所有单个项目的引用会对拥有大量约会项目,联系人和任务的用户使用大量内存。
我的问题是关于我保留引用的底层COM对象。此对象是否包含项目的所有详细信息,或者它只是Outlook用于从数据存储区加载详细信息的指针。例如,当我访问Contact项的FirstName属性时,它是直接从内存加载还是从Outlook PST文件加载。
答案 0 :(得分:4)
我不建议保留对每个日历项目,任务和联系人的引用。这将使大部分RCW成为gen 1或gen 2,这意味着他们不太可能被垃圾收集清理干净。对象本身永远不会进入.net空间,但每个对象都会得到RCW,这会阻止内存在非托管端清理。这也可能导致Outlook中日历项目被锁定而您无法调整大小以及其他随机问题的问题......
我建议改为使用我的VSTO Contrib项目中的FolderMonitor类(http://vstocontrib.codeplex.com/SourceControl/changeset/view/50a83624e34d#src%2fVSTOContrib.Outlook%2fOutlookFolderMonitor.cs)删除项目时删除的事件,这样您只能引用3 RCW(联系人文件夹,任务文件夹和日历文件夹)。
答案 1 :(得分:3)
这几乎肯定是从内存中加载的。但是当您创建 COM对象时,您对Outlook的压力就会发生,那么Outlook必须做任何事情来获取对象数据。它可能会一直存在,直到您停止引用该对象并且终结器线程运行。但可以肯定的是,如果您引用所有内容,那么您可能会给Outlook带来困难。过多的内存和页面文件使用是麻烦的症状。
这只是猜测,Outlook的内部结构没有记录。我建议你尝试创建一个真实的负载,并看看像SysInternals的Process Explorer这样的工具。
答案 2 :(得分:3)
你可能在这里交叉工作
这是来自BEFOREDELETED事件的帮助
为了让这个事件在什么时候开火 电子邮件,分发列表, 日记帐分录,任务,联系人或职位 通过动作删除, 检查员必须开放。
“检查员必须打开”这句话是关键。您将无法为每个电子邮件,联系人和日历项打开检查员。 BeforeDeleted事件仅适用于用户在Outlook中实际打开的那些项目。
您可能想要做的是获取对特定FOLDER对象的引用并监视该文件夹上的事件(我相信它是BEFOREITEMMOVE,这很奇怪,但删除项目基本上是将它移动到垃圾箱)。
因为我看过前景已经有一段时间了,所以我的命名可能有点过了......