钩子事件Outlook VSTO在主线程上继续工作

我开发了一个Outlook VSTO插件。 有些任务应该在后台线程上完成。 通常,检查本地数据库中的某些内容或调用Web请求。 在阅读了几篇文章之后,我放弃了在后台线程中调用Outlook对象模型(OOM)的想法。

我有一些wpf控件,我成功地设法使用.NET 40 TPL执行异步任务,并在完成时“完成”主VSTA线程中的作业(即访问UI或OOM)。

为此,我使用以下forms的语法:

Task task = Task.Factory.StartNew(()=>{ //Do long tasks that have nothing to do with UI or OOM return SomeResult(); }); //now I need to access the OOM task.ContinueWith((Task tsk) =>{ //Do something clever using SomeResult that uses the OOM },TaskScheduler.FromCurrentSynchronizationContext()); 

到现在为止还挺好。 但是现在我想在OOM中挂钩没有Form / WPF控件的事件时做类似的事情。 确切地说,我的问题来自于TaskScheduler.FromCurrentSynchronizationContext()抛出exception的事实。

例如,

 Items inboxItems = ...; inboxItems.ItemAdd += AddNewInboxItems; private void AddNewInboxItems(object item) { Task task = Task.Factory.StartNew(()=>{ //Do long tasks that have nothing to do with OOM return SomeResult()}); var scheduler = TaskScheduler.FromCurrentSynchronizationContext(); /* Ouch TaskScheduler.FromCurrentSynchronizationContext() throws an InvalidOperationException, 'The current SynchronizationContext may not be used as a TaskScheduler.' */ task.ContinueWith((Task tsk) =>{ //Do something clever using SomeResult that uses the OOM }),scheduler}; } 

/ * Ouch TaskScheduler.FromCurrentSynchronizationContext()抛出InvalidOperationException,’当前的SynchronizationContext可能不会被用作TaskScheduler。’ * /

请注意,我尝试在addin初始化中创建一个TaskScheduler,并按照此处的建议将其放入单例中。 但它不起作用,延续任务不是在所需的VSTA主线程中执行,而是在另一个线程中执行(使用VisualStudio检查)。

任何的想法 ?

已知错误,SynchronizationContext.Current可能在不应该的几个地方(包括办公室加载项)为空。 该错误已在.NET 4.5中修复。 但由于无法升级到.NET 4.5,因此必须找到解决方法。 作为建议,尝试做:

 System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext()); 

初始化你的插件时。

您可以使用SynchronizationContext类,该类提供在各种同步模型中传播同步上下文的基本function。 Post方法将异步消息调度到同步上下文,即Post方法启动异步请求以发布消息。 有关更多信息和示例代码,请参阅使用SynchronizationContext将事件发送回WinForms或WPF的UI 。

FYI Current属性允许获取当前线程的同步上下文。 此属性对于将同步上下文从一个线程传播到另一个线程非常有用。