Pergunta

Eu tenho um aplicativo C # que usa um componente COM. Este componente COM requerem uma bomba de mensagem (Application.Run ()) para fazer o seu processamento. Isto significa que é ficado preso no segmento principal. Mas eu descobri recentemente que é possível iniciar outra Application.Run em outro segmento que recebe o seu próprio ApplicationContext.

Então eu quero hospedar o componente COM no seu próprio segmento dentro de seu próprio Application.Run (), mas eu não consigo descobrir como fazer as coisas iniciados no novo segmento, sem criar uma forma UI.

O WindowsFormsSynchronizationContext I necessidade de se comunicar com o segmento não são criados até Application.Run (). Mas uma vez Application.Run () é chamado, eu não consigo descobrir como obter no SynchronizationContext. Se eu pudesse levantar um único evento nesse segmento, eu poderia usar isso para inicializar a coisa toda (criar o objeto COM, etc.), mas não parece estar em qualquer lugar para ligar para o novo ciclo de eventos sem um formulário .

Eu tentei todos os tipos de coisas complicadas, como a instalação de um filtro de mensagens (sem mensagens são levantadas sobre o novo segmento), copiando o contexto de execução em outro segmento e tentando recuperar o SynchronizationContext de lá (ele se recusa a copiar o ExecutionContext de um fio já em execução), recuperando Thread.CurrentContext antes de iniciar Application.Run () e, em seguida, chamando DoCallbBack () (a DoCallback acaba no segmento original), etc. Nada que eu tentei obras.

Foi útil?

Solução

Bryce,

Você pode ser capaz de se adaptar esse trecho de Anders do Hejlsberg palestra sobre "O Futuro do C #". é um pouco de classe que adiciona uma bomba de mensagem para um segmento para que ele possa abrir janelas usando um loop REPL, e eles terão uma bomba de mensagem que lhes são inerentes.

Os olhares código como este:

using System.Windows.Forms;
using System.Threading;
class UserInterfaceThread()
{
    static Form window;

    public UserInterfaceThread() 
    {
        var thread = new Thread(() => {
            window = new Form();
            var handle = window.Handle;
            Application.Run();
            });
        thread.Start();
    }
    public void Run(Action action)
    {
        window.Invoke(action);
    }
}

A discussão relativa a este código ocorre em 1 hora e 5 minutos para falar Anders', se você quiser revê-lo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top