2015-02-23 3 views
0

Я пытаюсь подключиться к событию ItemSend (который должен срабатывать, когда пользователь нажимает «Отправить» в Outlook), но проблема у меня есть, если GC запускается перед пользователем клики «Отправить», кейс события потерян. Я проверил это, вызывая gc.Collect. Я использую Outlook 2007 с последним пакетом обновления. Сначала я думал, что проблема связана с областью видимости, но я все это убрал и все еще не могу определить, почему мой крюк событий удаляется. Может кто-нибудь пролить некоторый свет на это? большое спасибо.Interop Outlook 2007 потеряет событие ItemSend после коллекции Garbage

справочный проект: 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("[email protected]"); 
      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 
     } 
    } 
} 

ответ

4

Вы используете несколько обозначений точек, что означает, что компилятор создает неявную переменную для хранения значения, и как только эта переменная выходит из области видимости, он получает право на сбор мусора , и когда GC пройдет несколько секунд спустя, события больше не будут подняты.

Изменение линии

outlook.Application.ItemSend += ThisApplication_SentMail; 

в

outlook.ItemSend += ThisApplication_SentMail; 
+0

Спасибо Dmitry –

+0

Да - спасибо. Все работало в модульных тестах и ​​в течение первых 90 секунд или около того, что мое приложение запускалось, - тогда оно прекратилось. –

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("[email protected]"); 
     mailItem.Body = "test123"; 
     mailItem.Display(true); 

См Microsoft's Documentation on Display

+0

Большое спасибо Рою. И ваше «я», и «Дмитрий» попали прямо на гвоздь, спасибо вам за ваши информационные ответы. –

Смежные вопросы