Interop Outlook 2007 在垃圾收集后丢失 ItemSend 事件
Interop Outlook 2007 losing ItemSend event after Garbage Collection
我正在尝试挂钩 ItemSend 事件(一旦用户在 Outlook 中单击 "Send",该事件就会触发),但我遇到的问题是 GC 在用户单击 [=15= 之前是否触发] 事件挂钩丢失。我已经通过强制 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
}
}
}
这在技术上是正确的,因为它是处置问题。看来,当 window 从您的应用程序分离时,事件将断开连接。
如果将 Display 设置为 True,您应该会发现这不会发生。模态标志的目的就是专门为此。如果您需要锁定当前线程直到用户完成,请使用 true,否则使用 false(或什么都不做)。
Modal Optional Variant
True to make the window modal. The default value is False.
例如
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);
您使用的是多点表示法,这意味着编译器会创建一个隐式变量来保存该值,一旦该变量超出范围,它就有资格进行垃圾回收,并且当 GC 运行一些几秒钟后,将不再引发事件。
换行
outlook.Application.ItemSend += ThisApplication_SentMail;
至
outlook.ItemSend += ThisApplication_SentMail;
我正在尝试挂钩 ItemSend 事件(一旦用户在 Outlook 中单击 "Send",该事件就会触发),但我遇到的问题是 GC 在用户单击 [=15= 之前是否触发] 事件挂钩丢失。我已经通过强制 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
}
}
}
这在技术上是正确的,因为它是处置问题。看来,当 window 从您的应用程序分离时,事件将断开连接。 如果将 Display 设置为 True,您应该会发现这不会发生。模态标志的目的就是专门为此。如果您需要锁定当前线程直到用户完成,请使用 true,否则使用 false(或什么都不做)。
Modal Optional Variant
True to make the window modal. The default value is False.
例如
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);
您使用的是多点表示法,这意味着编译器会创建一个隐式变量来保存该值,一旦该变量超出范围,它就有资格进行垃圾回收,并且当 GC 运行一些几秒钟后,将不再引发事件。
换行
outlook.Application.ItemSend += ThisApplication_SentMail;
至
outlook.ItemSend += ThisApplication_SentMail;