Interop Outlook 2007在垃圾收集后丢失ItemSend事件

时间:2015-02-23 21:55:32

标签: c# events outlook garbage-collection

我试图挂钩ItemSend事件(一旦用户点击"发送"在outlook中,它就应该触发),但我遇到的问题是如果GC在用户点击&之前触发#34;发送"事件挂钩丢失了。我通过强制gc.Collect测试了这个。我使用outlook 2007和最新的服务包。起初我认为这个问题是由于范围问题,但我已经删除了所有内容,但仍无法确定为什么我的事件挂钩被删除。任何人都可以对此有所了解吗?非常感谢。

项目参考: Microsoft.Office.Interop.Outlook

using System.Windows.Forms;
using Microsoft.Office.Interop.Outlook;

namespace WindowsFormsApplication20
{
    public partial class Form1 : Form
    {
        private Microsoft.Office.Interop.Outlook.Application outlook;
        private MailItem mailItem;

        public Form1()
        {
            InitializeComponent();

            outlook = new Microsoft.Office.Interop.Outlook.Application();
            outlook.Application.ItemSend += ThisApplication_SentMail;

            mailItem = (MailItem)outlook.CreateItem(OlItemType.olMailItem);
            mailItem.Recipients.Add("asd@hotmail.com");
            mailItem.Body = "test123";
            mailItem.Display();

            // when gc collect, ItemSend event no longer fires (force gc.collect to test)
            System.GC.Collect();
        }

        private void ThisApplication_SentMail(object item, ref bool cancel)
        {
            int halt = 0; //breakpoint here
        }
    }
}

2 个答案:

答案 0 :(得分:4)

您正在使用多点符号,这意味着编译器会创建一个隐式变量来保存该值,并且一旦该变量超出范围,它就有资格进行垃圾回收,并且当GC运行几秒钟后,事件将不再被提出。

更改行

outlook.Application.ItemSend += ThisApplication_SentMail;

outlook.ItemSend += ThisApplication_SentMail;

答案 1 :(得分:2)

这在处理问题上在技术上是正确的。当窗口与您的应用程序分离时,该事件似乎已断开连接。 如果将Display设置为True,您会发现这不会发生。模态标志的目的是专门为此。如果需要锁定当前线程直到用户完成,请使用true,否则使用false(或不使用)。

Modal Optional Variant
True to make the window modal. The default value is False.

E.g。

        outlook = new Microsoft.Office.Interop.Outlook.Application();
        outlook.Application.ItemSend += ThisApplication_SentMail;

        mailItem = (MailItem)outlook.CreateItem(OlItemType.olMailItem);
        mailItem.Recipients.Add("asd@hotmail.com");
        mailItem.Body = "test123";
        mailItem.Display(true);

请参阅Microsoft's Documentation on Display