Pergunta

VS2008, .NET 2, VB.NET, XP ...

Eu tenho um formulário do Windows, com um controle WebBrowser e um botão Fechar, que apenas faz um Me.Close. Do formulário cancelar botão está definido para o botão Fechar, para que eu possa bater ESC para fechar o formulário.

I definir a propriedade DocumentText do controle WebBrowser no evento de carregamento, e os monitores HTML.

A execução do aplicativo a partir do Visual Studio, se eu clicar no botão Fechar, o fechamento do formulário com nenhum erro.

Se eu acertar o botão ESC I get

RaceOnRCWCleanup foi detectado Mensagem: Uma tentativa foi feita para libertar um RCW que está em uso. o RCW está em uso na linha activa ou outro segmento. A tentativa de um livre em uso RCW pode causar corrupção ou perda de dados.

Se eu executar o aplicativo fora VS, recebo nenhum erro.

Todas as ideias a) Por que o erro, e b) como prevenir ou suprimi-lo?

Muito obrigado antecipadamente.

Foi útil?

Solução

Não é um erro, ele é um aviso. Produzido por um assistente Gerenciado depuração (MDA), uma extensão para o depurador para código gerenciado, que pensa que está vendo algo errado em seu código. O sapato se encaixa. Você está usando um RCW, WebBrowser é um controle COM. Você está matando o RCW, você está fechando seu formulário. O MDA passos no sistema porque ele pensa que está vendo o navegador em uso e ser morto antes que a solicitação seja concluída. Que normalmente só fazem sentido se você estiver usando um fio em seu código.

E você? Se não, não perca o sono por isso. COM usa contagem de referência, notório por não ser capaz de resolver referências circulares.


Ok, eu tenho um repro para isso, habilitado pelos comentários. Sim, esta é desencadeada por propriedade CancelButton do formulário ou a propriedade DialogResult do botão. Isso acontece quando a WB tem o foco, ele vê o pressione a tecla Escape. Parte do encanamento ActiveX é dizer o recipiente sobre ele para que ele possa responder ao comando das teclas que devem ter um efeito colateral. combinações de teclas de atalho, Tab, Enter. E Escape. Se o botão, em seguida, fecha o formulário, o depurador vê o WB se eliminados, embora existam quadros de pilha ativos a partir do código RCW na pilha. O perigo é que isso pode causar um acidente quando os chamados retornos de código desde o componente COM foi lançado, não é incomum.

Vendo este acidente é bastante improvável, mas posso imaginar que isso poderia bombardear quando o segmento finalizador é executado pouco antes de retornos evento Click do botão. A solução alternativa para o MDA e o acidente potencial é para atrasar fechar o formulário até que o código ActiveX pára de funcionar. Elegantemente feito com Control.BeginInvoke (). Como esta:

    private void CancelButton_Click(object sender, EventArgs e) {
        this.BeginInvoke((MethodInvoker)delegate { this.Close(); });
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top