我开发了一个 Outlook VSTO 插件。有些任务应该在后台线程上完成。通常,检查本地数据库中的某些内容或调用网络请求。阅读了几篇文章后,我放弃了在后台线程中调用 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());
到目前为止,一切都很好。但现在我想在没有 Form/WPF 控件的 OOM 中挂钩事件时执行类似的操作。准确地说,我的问题来自于这样一个事实: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};
}
/* Ouch TaskScheduler.FromCurrentSynchronizationContext() 抛出 InvalidOperationException,“当前 SynchronizationContext 不能用作 TaskScheduler。” */
请注意,我尝试在插件初始化中创建一个 TaskScheduler 并将其按照建议放入单例中here https://stackoverflow.com/questions/4659257/how-can-synchronizationcontext-current-of-the-main-thread-become-null-in-a-windo。但它不起作用,延续任务不是在所需的 VSTA 主线程中执行,而是在另一个线程中执行(使用 VisualStudio 检查)。
任何想法 ?