Ho una libreria C# che vorrebbe avere la possibilità di inviare/inviare messaggi al thread dell'interfaccia utente "principale" (se ne esiste uno). Questa libreria può essere utilizzato da:Cattura il thread principale SynchronizationContext o Dispatcher da una libreria
- Un'applicazione WinForms
- Un'applicazione nativa (con UI)
- un'applicazione console (senza interfaccia utente)
Nella biblioteca che avevo piace catturare qualcosa (A SynchronizationContext, un Dispatcher, un Task Scheduler, o qualcos'altro) durante l'inizializzazione, che mi permetterà di (in un secondo momento) Invia/Invia lavoro al thread principale (se il thread principale ha quell'abilità- -ha ha un messaggio pompa). Ad esempio, la libreria vorrebbe mettere l'interfaccia utente di Winforms sul thread principale se e solo se l'applicazione principale ha la possibilità per me di accedere al thread principale.
Le cose che ho provato:
- A SynchronizationContext:. Catturare questo funziona bene per un'applicazione WinForms (un WindowsFormsSynchronizationContext verrà installato come Current SynchronizationContext questo funziona bene anche per la console app - dal Posso rilevare che Current SynchronizationContext è null (e quindi, so che non ho la possibilità di inviare/inviare lavoro al thread principale.) Il problema qui è l'applicazione UI nativa: ha l'abilità (cioè ha un messaggio pump), ma il contesto Current Synchronization è nullo e quindi non posso distinguerlo dal caso dell'app Console. Se potessi differenziare, potrei semplicemente installa un WindowsFormsSynchronizationContext sul thread principale e sono a posto.
- A Dispatcher: Catturare questo utilizzando Current crea un nuovo SynchronizationContext. Quindi, in tutte le situazioni tornerò su un Dispatcher. Tuttavia, per un'app Console, l'utilizzo di
Dispatcher.Invoke
da un thread in background verrà interrotto (come previsto). Potrei usareDispatcher.FromThread
(che non crea un Dispatcher per il thread se uno non esiste). Ma l'applicazione di interfaccia utente nativa restituirà un Dispatcher nullo con questo metodo e quindi, di nuovo, non riuscirò a distinguere l'applicazione dell'interfaccia utente dall'applicazione console. - A TaskScheduler: Potrei usare FromCurrentSynchronizationContext. Questo ha gli stessi problemi di SynchronizationContext. Cioè Prima di chiamare FromCurrentSyncronizationContext, dovrei controllare se Current SynchronizationContext è nullo (che sarà il caso per l'app Console e l'applicazione ui nativa). Quindi, ancora una volta non riesco a distinguere l'applicazione ui nativa dall'applicazione console.
Io, naturalmente, potrei avere l'utente della mia biblioteca specificare se si tratta di un'applicazione UI quando chiamano il mio metodo Initialize
, ma speravo di evitare che complicazioni per l'utente della biblioteca, se possibile .
Sto usando la libreria C# in MFC. Questa libreria ha una chiamata TaskScheduler.FromCurrentSynchronizationContext(). quando eseguo l'applicazione MFC genera un'eccezione dicendo che "l'attuale SynchronizationContext non può essere usato come un TaskScheduler". Qualche idea su come affrontarla?Non sto utilizzando direttamente la libreria C# in MFC, ma ho creato un wrapper nel C++ gestito e sto usando questo wrapper nell'applicazione MFC. –