2010-09-03 44 views
2

我正在创建一个Outlook邮件项目对象并监视发送事件。所有显示都很好,但是当Send事件触发时,事件在我的应用程序的后台线程中引发。这是一个问题,原因是此事件创建了通过我的应用程序发送的电子邮件记录,该电子邮件被添加到对象集合中。因此,该集合引发后台线程上的List Changed事件,从而在显示该集合的控件上导致跨线程控制访问。在后台线程上引发的Outlook电子邮件发送事件

这里是我的事件联播:

((Outlook.ItemEvents_10_Event)item).Send += new Microsoft.Office.Interop.Outlook.ItemEvents_10_SendEventHandler(ItemSendWatcher_Send); 

该事件在保持该消息的引用的基本类迷上了发送,并委托时提出的发送事件来调用。这允许我将电子邮件对象的实例传递给委托。

这是我的处理程序:

void ItemSendWatcher_Send(ref bool Cancel) 
    { 
     if (itemSendDelegate != null) 
     { 
      this.itemSendDelegate(this.item, ref Cancel); //The delegate with the mail item 
     } 
     Marshal.ReleaseComObject(item); 
     itemSendDelegate = null; 
    } 

这是该事件的正确的行为还是我构造对象时做错了什么?谢谢你的帮助。

编辑:只是为了澄清,我没有处理UI层中的事件,而是处理业务对象。从发送事件处理程序调用的委托会导致在内部将新对象添加到列表中,这会导致列表的ListChanged事件被引发,导致在显示此列表的控件中调用处理程序。我希望这能澄清我试图达到的目标。

+1

你能展示更多的代码吗? – 2010-09-03 11:36:18

+0

现在稍微更清晰,这是一个已知的问题:http://stackoverflow.com/questions/2354438/mvvm-best-practice-to-pass-dispatcher-to-the-viewmodel – 2010-09-03 13:05:45

回答

1

很多形式事件在主窗口线程,这意味着你往往不必过分担心横纱的担忧上提出的。但是没有保证,COM通常不会在该线程上引发事件。解决方案是调用this.Invoke(..)与委托给方法或匿名块来执行必要的工作在正确的线程。测试这是否有必要测试this.InvokeRequired。

+0

Invoke和InvokeRequired不可用,因为该类不是控件。这就是为什么我在之前的回答中评论如果我需要创建控件的实例以允许我调用Invoke。 – GaryJL 2010-09-03 12:33:03

+0

无论您在处理程序中更改什么内容(即显示列表的控件),都需要使用Invoke。 – 2010-09-03 12:38:15

+0

我明白了 - 这很有道理!问题在于,在处理事件期间的任何阶段,我都无法访问控件,除非列表更改事件在我的集合类中引发。时间来重构我想! – GaryJL 2010-09-03 12:46:18

1

您需要处理InvokeRequired +调用内部ItemEvents_10_SendEventHandler()

+0

我假设你的意思是创建一个实例控制在这将允许我调用处理程序使用control.Invoke? – GaryJL 2010-09-03 12:01:33

+0

不,请查看如何使用Control.Invoke和InvokeRequired。创建控件没有什么特别的。发布事件处理程序的代码以获得更好的答案。 – 2010-09-03 12:17:04

+0

事件处理程序的代码存在于问题中。 – GaryJL 2010-09-03 12:21:41