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

Ben*_*tra 19 c# outlook multithreading vsto outlook-addin

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

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

为此,我使用了以下形式的语法:

Task<SomeResult> 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<SomeResult> tsk) =>{
   //Do something clever using SomeResult that uses the OOM
},TaskScheduler.FromCurrentSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

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

例如,

Items inboxItems = ...;
inboxItems.ItemAdd += AddNewInboxItems;

private void AddNewInboxItems(object item)
{
    Task<SomeResult> 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<SomeResult> tsk) =>{
       //Do something clever using SomeResult that uses the OOM
   }),scheduler};
}
Run Code Online (Sandbox Code Playgroud)

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

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

任何的想法 ?

Evk*_*Evk 12

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

System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
Run Code Online (Sandbox Code Playgroud)

初始化你的插件时.

  • 嗨,.NET 4.0和.NET 4.5中的SynchronizationContext.Current都为null.但是,使用WindowsFormsSynchronizationContext的解决方案有效.我会授予你赏金.谢谢 (5认同)