Pergunta

...ou...

"Que mal nas profundezas do WPF eu acordei?"

Estou criando uma tela em um encadeamento de segundo plano e renderizando -o em um bitmap. Eu tenho esse trabalho no código de produção há mais de um ano sem problemas. Eu faço o seguinte:

  • Crie um objeto de tela
  • Crie um novo objeto de nomes
  • Atribua esse nome de nome à tela
  • desenhe o que eu quiser na tela
  • Ligue para Canvas.measure () com o tamanho da tela
  • Ligue para Canvas.arrage () com o rect disponível da tela
  • Ligue para Canvas.UpDateLayout ()
  • renderizar a tela

Na etapa de empate, sempre chamei Canvas.Children.add () para colocar em uielledos na tela. Isso sempre funcionou.

Agora, por algum motivo inexplicável, em um caso específico no aplicativo em que estou trabalhando, a chamada para Canvas.Children.Add () fica indefineiamente, bloqueando meu thread de fundo. Não consigo pensar em nada que estou fazendo de maneira diferente entre o código que trabalha há mais de um ano e este caso específico.

Alguém pode sugerir possíveis razões pelas quais uma chamada para Canvas.Children.Add () penduraria assim?

Editar: O encadeamento de segundo plano é um encadeamento STA (o modelo de processamento de encadeamento em segundo plano foi implementado porque eu não conseguia processar imagens usando o WPF em um thread MTA); portanto, o modelo de apartamento de thread não deve ser o culpado.

Editar #2: Enquanto eu entendo por que as pessoas estão sugerindo que eu tente o Dispatcher.begininvoke () do meu tópico de segundo plano, não gosto dessa opção por dois motivos:

  1. Eu quero que meu processamento de thread de fundo seja síncrono nesse tópico. Meu tópico de plano de fundo tem uma fila para a qual outros threads enviam trabalhos de imagem e meu encadeamento de segundo plano processa cada trabalho que chega a eles. O uso do Dispatcher.BegininVoke () adiciona outra camada de complexidade que eu prefiro evitar.
  2. Eu nunca precisava até agora. Fazer esse processamento de fundo de forma síncrona no meu tópico de fundo acabou de trabalhado. Estou tentando determinar o que poderia ser diferente nesse caso bizarro de borda que faz com que esse código não funcione. Se eu não conseguir funcionar, acabarei reescrevendo esse código de processamento sem o WPF, que também prefiro evitar.
Foi útil?

Solução

Que modelo de apartamento você está usando para o seu tópico de segundo plano?

Eu acredito que o WPF precisa ser executado no tópico STA. Quando você gerar o tópico de fundo, tente configurar o apartamento para o STA.

Atualizar:

Se o thread STA não for o problema, eu tentaria quebrar sua tela se elaborando em pedaços. Basicamente, se você fizer um:

Dispatcher.Begininvoke (...)

A partir do seu tópico, o delegado fornecido é empurrado para a parte traseira da fila do despachante, permitindo que outras tarefas na fila sejam executadas.

Atualização 2:

Você também pode tentar depurar o código -fonte do objeto Canvas usando as fontes de referência do .NET Framework. Você pode ativar isso ativando o "Ativar .NET Framework Source Spicking" nas opções de depuração em Ferramentas-> Opções.

Outras dicas

Tente chamar o Dispatcher.run () no encadeamento de segundo plano.

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