Ho sviluppato un add-in per Outlook VSTO. Alcune attività dovrebbero essere eseguite su un thread in background. In genere, controllare qualcosa nel mio db locale o richiamare una richiesta web. Dopo aver letto diversi post, ho abbandonato l'idea di chiamare Outlook Object Model (OOM) in un thread in background.Eventi collegati Eventi continui di VSTO su thread principale
Ho alcuni controlli wpf e sono riuscito a utilizzare .NET 40 TPL per eseguire l'attività asincrona e una volta completato per "terminare" il lavoro (ovvero accedere all'interfaccia utente o all'OOM) nel thread VSTA principale.
Per fare in modo da utilizzare una sintassi del tipo:
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());
Fin qui tutto bene. Ma ora voglio fare qualcosa di simile quando si collega un evento nell'OOM dove non ci sono controlli Form/WPF. Precisamente, il mio problema deriva dal fatto che TaskScheduler.FromCurrentSynchronizationContext() genera un'eccezione.
Ad esempio,
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() genera InvalidOperationException, 'Lo SynchronizationContext corrente non può essere usato come TaskScheduler.' */
Si noti che ho cercato di creare un TaskScheduler in inizializzazione Addin e metterlo in un singleton come suggerito here. Ma non funziona, il task di continuazione non viene eseguito nel thread principale VSTA desiderato ma in un altro (ispezionato con VisualStudio).
Qualche idea?
Hai provato async/attendi? –
No, non l'ho perché ho il targeting per .NET40. L'aggiornamento a .NET45 non è un'opzione per ora. Tuttavia, hai ragione, ti darò una possibilità, questo potrebbe portare qualche intuizione per una correzione in 40. –
@DmitryStreblechenko purtroppo dopo la parola chiave * await * il thread che sta eseguendo il resto dell'attività non è il thread VSTA principale. –