【问题标题】:Outlook Email Send event raised on Background Thread在后台线程上引发的 Outlook 电子邮件发送事件
【发布时间】:2011-04-07 19:12:15
【问题描述】:

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

这是我的活动联播:

((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 事件,从而导致在显示此列表的控件中调用处理程序。我希望这能阐明我想要实现的目标。

【问题讨论】:

标签: c# .net outlook-2007 outlook-object-model


【解决方案1】:

在主窗口线程上引发了许多 Forms 事件,这意味着您通常不必过多担心跨线程问题。但是,没有任何保证,COM 通常不会在该线程上引发事件。解决方案是调用 this.Invoke(..) 并使用方法委托或匿名块在正确的线程上执行必要的工作。要测试这是否必要,请测试 this.InvokeRequired。

【讨论】:

  • Invoke 和 InvokeRequired 不可用,因为该类不是控件。这就是为什么我在对先前答案的评论中询问是否需要创建控件实例以允许我调用 Invoke。
  • 您需要在处理程序中更改的任何内容上使用 Invoke - 显示列表的控件。
  • 我明白了——这很有道理!问题是,在处理事件的任何阶段,我都无法访问控件,除非在我的集合类中引发了列表更改事件。我认为是时候重构了!
【解决方案2】:

你需要在ItemEvents_10_SendEventHandler()里面处理InvokeRequired + Invoke

【讨论】:

  • 我假设您的意思是在类中创建一个控件实例,这将允许我使用 control.Invoke 调用处理程序?
  • 不,只是看看如何使用 Control.Invoke 和 InvokeRequired。创建控件没有什么特别之处。发布事件处理程序的代码以获得更好的答案。
  • 事件处理程序的代码在问题中。
  • 更多信息添加到问题中。
猜你喜欢
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 2011-09-13
  • 2010-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多