挂钩事件Outlook VSTO在主线程上继续工作 [英] Hooked events Outlook VSTO continuing job on main Thread

查看:72
本文介绍了挂钩事件Outlook VSTO在主线程上继续工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have developed an Outlook VSTO addin. Some tasks should be made on a background thread. Typically, checking something in my local db or invoking a web request. After reading several posts, I dropped the idea of calling the Outlook Object Model (OOM) in a background thread.

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

I have some wpf controls and I successfully managed to use the .NET 40 TPL to perform the async task and when completed to "finish" the job (i.e. accessing the UI or the OOM) in the Main VSTA Thread.

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

To do so I use a syntax of the form:

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());

到目前为止,一切都很好.但是现在我想在没有Form/WPF控件的OOM中挂接事件时做类似的事情.确切地说,我的问题来自 TaskScheduler.FromCurrentSynchronizationContext()引发异常的事实.

So far so good. But now I want to do something similar when hooking an event in the OOM where there are no Form/WPF control. Precisely, my problem comes from the fact that TaskScheduler.FromCurrentSynchronizationContext() throws an exception.

例如,

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};
}

/*哎呀TaskScheduler.FromCurrentSynchronizationContext()抛出InvalidOperationException,当前的SynchronizationContext可能不用作TaskScheduler." */

/* Ouch TaskScheduler.FromCurrentSynchronizationContext() throws an InvalidOperationException, 'The current SynchronizationContext may not be used as a TaskScheduler.' */

请注意,我尝试在外接程序初始化中创建一个TaskScheduler,并按照建议将其放在单例中

Note that I tried to create a TaskScheduler in addin initialization and putting it in a singleton as suggested here. But it does not work, the continuation task is not performed in the desired VSTA Main thread but another one (inspected with VisualStudio).

有什么主意吗?

推荐答案

有一个已知的错误,即SynchronizationContext.Current在一些不应包含的地方(包括Office加载项)可能为null.该错误已在.NET 4.5中修复.但是,由于无法升级到.NET 4.5,因此必须找到一种解决方法.建议,尝试执行以下操作:

There is known bug that SynchronizationContext.Current might be null in several places where it should not (including office add-ins). That bug was fixed in .NET 4.5. But since you cannot upgrade to .NET 4.5, you have to find a workaround. As a suggestion, try to do:

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

初始化插件时.

这篇关于挂钩事件Outlook VSTO在主线程上继续工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆