c# - Eventos enganchados Trabajo continuo de Outlook VSTO en el hilo principal
multithreading outlook-addin (2)
Existe un error conocido de que SynchronizationContext.Current puede ser nulo en varios lugares donde no debería (incluidos los complementos de Office). Ese error fue corregido en .NET 4.5. Pero como no puede actualizar a .NET 4.5, tiene que encontrar una solución alternativa. Como sugerencia, trate de hacer:
System.Threading.SynchronizationContext.SetSynchronizationContext(new WindowsFormsSynchronizationContext());
Al inicializar tu complemento.
He desarrollado un complemento de Outlook VSTO. Algunas tareas deben hacerse en un hilo de fondo. Normalmente, verificando algo en mi base de datos local o invocando una solicitud web. Después de leer varias publicaciones, descarté la idea de llamar al Modelo de objetos de Outlook (OOM) en un hilo de fondo.
Tengo algunos controles de wpf y logré usar .NET 40 TPL para realizar la tarea asíncrona y cuando finalicé para "finalizar" el trabajo (es decir, acceder a la UI o la OOM) en el subproceso principal de VSTA.
Para ello utilizo una sintaxis del formulario:
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());
Hasta ahora tan bueno. Pero ahora quiero hacer algo similar al conectar un evento en la OOM donde no hay control de Form / WPF. Precisamente, mi problema proviene del hecho de que TaskScheduler.FromCurrentSynchronizationContext () lanza una excepción.
Por ejemplo,
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 () lanza una InvalidOperationException, ''El SynchronizationContext actual no se puede usar como un TaskScheduler''. * /
Tenga en cuenta que intenté crear un TaskScheduler en la inicialización del complemento y ponerlo en un singleton como se sugiere here . Pero no funciona, la tarea de continuación no se realiza en el subproceso principal de VSTA deseado, sino en otro (inspeccionado con VisualStudio).
Alguna idea ?
Puede usar la clase SynchronizationContext que proporciona la funcionalidad básica para propagar un contexto de sincronización en varios modelos de sincronización. El método Post distribuye un mensaje asíncrono a un contexto de sincronización, es decir, el método Post inicia una solicitud asíncrona para publicar un mensaje. Consulte Uso de SynchronizationContext para enviar eventos de nuevo a la interfaz de usuario de WinForms o WPF para obtener más información y código de muestra.
FYI La propiedad Current permite obtener el contexto de sincronización para el hilo actual. Esta propiedad es útil para propagar un contexto de sincronización de un hilo a otro.