Я разработал Outlook VSTO addin. Некоторые задачи должны выполняться в фоновом потоке. Как правило, проверка чего-то в моем локальном db или вызов веб-запроса. После прочтения нескольких сообщений я отказался от идеи вызова объектной модели Outlook (OOM) в фоновом потоке.Подключенные события Outlook VSTO продолжение работы на главной теме
У меня есть некоторые элементы управления wpf, и я успешно смог использовать .NET 40 TPL для выполнения задачи async и по завершении «завершить» задание (т. Е. Получить доступ к пользовательскому интерфейсу или OOM) в главной теме VSTA.
Для этого я использую синтаксис вида:
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());
До сих пор так хорошо. Но теперь я хочу сделать что-то подобное при подключении события в 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};
}
/* Ай TaskScheduler.FromCurrentSynchronizationContext() выбрасывает InvalidOperationException, 'Ток SynchronizationContext не может быть использован в качестве TaskScheduler. */
Обратите внимание, что я попытался создать TaskScheduler в инициализации addin и поместив его в одноэлементный режим, как предлагается here. Но он не работает, задача продолжения не выполняется в нужном главном потоке VSTA, а другая (проверяется с помощью VisualStudio).
Любая идея?
Вы пытались использовать async/wait? –
Нет У меня нет, потому что я нацелен на .NET40. Обновление до .NET45 сейчас не является вариантом. Тем не менее, вы правы, я попробую, это может принести некоторые сведения о исправлении в 40. –
@DmitryStreblechenko, к сожалению, после ключевого слова * await * поток, выполняющий остальную часть задачи, не является основным потоком VSTA. –