我有一个使用VSTO创建的Office插件(如果有所不同,则显示Outlook)。插件在启动时创建Windows窗体。我的表单创建了几个线程。我正在寻找具体的指导或人们对以下情况下安全工作的经验:
1。)Form创建的线程需要访问Office对象模型(Globals.ThisAddIn.Application)
2.。)由Form创建的线程不需要访问Office对象模型,但需要更新Windows窗体上的控件(窗体是由addin或'UI'线程创建的,因为我有时会听到它提到了)
对于上面的1.)我已经采用以下https://msdn.microsoft.com/en-us/library/8sesy69e%28v=vs.120%29.aspx表示只要将线程的单元状态设置为STA并处理异常,它就是安全的。但http://weblogs.asp.net/whaggard/all-outlook-object-model-calls-run-on-the-main-thread似乎暗示在.NET VSTO中,从任何后台线程调用对象模型都是安全的,因为它们会自动编组到主线程中,并且使'后台'线程STA仅用于表现原因。这就是它的全部吗?
For 2.)让'thread'成为Task或IsBackground线程是否有问题,只要它使用控件的InvokeRequired / Invoke模式?或者它是否需要是一个进行调用的STA线程?
更新 我见过几位VSTO专家提到不要在主线程以外的任何东西上触摸Outlook对象模型,而在Outlook 2013中,如果你这样做,它实际上会抛出一个错误。我有一个加载项实际上在几个后台线程(system.timers.timer,后台线程)上访问Outlook对象模型,我没有在我的日志中看到这样的错误。然后几天前突然间,我的插件的错误日志充满了以下错误,大约10分钟的时间跨度:
该应用程序调用了一个为不同线程编组的接口。 (来自HRESULT的异常:0x8001010E(RPC_E_WRONG_THREAD))
在这10分钟的跨度之后,错误神秘地消失了,我没有在错误发生之前和错误发生后立即对代码进行任何更改。在此之前,我已经在我的机器上运行了几个月的插件(主要是在缓存连接模式下,如果它很重要),没有看到任何这样的错误。
如果有人能指出我在Microsoft文档中说它不能在后台线程上访问对象模型,我会很高兴。
答案 0 :(得分:1)
绝对不支持辅助线程上的Outlook对象模型。不记得他们是否正式说了什么,但我个人从几位Outlook产品经理那里听说过。
扩展MAPI(或Redemption等MAPI包装器)是从辅助线程访问Outlook数据的唯一方法。