Tengo una biblioteca C# que desea tener la capacidad de enviar/publicar trabajo en el hilo "principal" de la interfaz de usuario (si existe). Esta biblioteca puede ser utilizada por:Capturar el hilo principal SynchronizationContext o Dispatcher de una biblioteca
- Una aplicación winforms
- Una aplicación nativa (con IU)
- Una aplicación de consola (sin interfaz de usuario)
En la biblioteca que había Me gusta capturar algo (un SynchronizationContext, un Dispatcher, un Scheduler de tareas u otra cosa) durante la inicialización, que me permitirá (en un momento posterior) enviar/publicar trabajo al hilo principal (si el hilo principal tiene esa habilidad). -es decir, tiene un mensaje de bomba). Por ejemplo, a la biblioteca le gustaría colocar alguna UI de Winforms en el hilo principal si y solo si la aplicación principal tiene la capacidad para llegar al hilo principal.
cosas que he intentado:
- Un SynchronizationContext:. La captura de esto funciona bien para una aplicación de Windows Forms (un WindowsFormsSynchronizationContext se instalará como el Current SynchronizationContext Esto también funciona bien para la aplicación de consola - desde Puedo detectar que el Current SynchronizationContext es nulo (y por lo tanto, sé que no tengo la capacidad de enviar/publicar trabajos en el hilo principal). El problema aquí es la aplicación de IU nativa: tiene la capacidad (es decir, tiene una bomba de mensajes), pero el contexto de Sincronización actual es nulo y, por lo tanto, no puedo diferenciarlo del caso de la aplicación de consola. Si pudiera diferenciarme, podría simplemente instale WindowsFormsSynchronizationContext en el hilo principal, y estoy listo para continuar.
- A Dispatcher: Capturando esto usando Current crea un nuevo SynchronizationContext. Por lo tanto, en todas las situaciones, recibiré un despachador. Sin embargo, para una aplicación de consola, el uso de
Dispatcher.Invoke
de un hilo de fondo se bloqueará (como se esperaba). Podría usarDispatcher.FromThread
(que no crea un despachador para el hilo si no existe uno). Pero la aplicación de UI nativa devolverá un Dispatcher nulo utilizando este método, y entonces, de nuevo, estoy atascado al no poder distinguir la aplicación de la interfaz de usuario de la aplicación de la consola. - A TaskScheduler: Podría usar FromCurrentSynchronizationContext. Esto tiene los mismos problemas que SynchronizationContext. Es decir. Antes de llamar a FromCurrentSyncronizationContext, tendría que verificar si el Current SynchronizationContext es nulo (lo cual será el caso para la aplicación de consola y la aplicación ui nativa). Entonces, nuevamente, no puedo distinguir la aplicación de interfaz de usuario nativa de la aplicación de consola.
Yo, por supuesto, podría tener el usuario de la biblioteca de mi especifica si es o no es una aplicación de interfaz de usuario cuando llaman mi método Initialize
, pero yo estaba esperando evitar esa complicación para el usuario de la biblioteca si es posible .
Estoy usando la biblioteca C# en MFC. Esta biblioteca tiene la llamada TaskScheduler.FromCurrentSynchronizationContext(). cuando ejecuto la aplicación MFC lanza una excepción que dice que 'SynchronizationContext actual no se puede usar como TaskScheduler'. ¿Alguna idea de cómo manejarlo?No estoy utilizando directamente la biblioteca C# en MFC, pero he creado un contenedor en C++ administrado y estoy usando este contenedor en la aplicación MFC. –