none
Tela congela, mas processo continua rodando em background RRS feed

  • Pergunta

  • Olá,

    Desenvolvi uma aplicação Windows Form (C#), que roda 24h. Nela eu realizo algumas consultas ao banco de dados, inserts, updates e gravação de arquivo texto.

    Até aí tudo bem, mas o que acontece é que em alguns momentos as informações que são atualizadas nos textbox e listbox da minha tela, param de atualizar. O processo continua rodando normalmente por trás, como se nada estivesse errado, mas a tela congela as informações do último registro antes de congelar.

    Existe um Timer que roda a cada 5 segundos, mas não sei se esse Timer pode me gerar esse tipo de erro.

    Alguém sabe como posso resolver este problema?

    Grato.


    segunda-feira, 18 de junho de 2012 11:24

Todas as Respostas

  • Toda aplicação Windows tem um limite de objetos gráficos que ela pode utilizar. Quanto isto chega ao fim, começam a ocorrer estes problemas, você não consegue mais desenhar objetos na tela.

    Ainda mais que o seu programa roda direto, você tem fazer algo para que seja removido de tempos em tempos os objetos graficos.


    Quem sabe um dia os DataSets se extinguirão?

    segunda-feira, 18 de junho de 2012 14:14
  • É recomendado que nessa situação, você utilize Thread para os processos que acessam o banco e apenas atualizar a tela quando receber a modificação dos dados.

    Assim não vai "travar" a tela.

    Veja: msdn.microsoft.com/pt-br/library/system.threading.thread.aspx


    If was useful mark as answered. Mariano, Paulo T. C.

    terça-feira, 19 de junho de 2012 15:29
  • Acho que entendi em partes...

    Por exemplo:

    À cada 5 segundos eu carrego informações novas em alguns TextBox.

    Rodando isso 24h eu tenho tido cerca de 5 congelamentos de tela, onde o processo continua rodando normalmente mas a tela só volta a carregar os dados se eu fecho e reabro a aplicação.

    Utilizar Refresh, Dispose, neste caso não ajudaria em nada, certo?

    Quando você fala em algo para remover os Objetos Gráficos, seria reconstruí-los em tempo de processamento?

    Grato.

    terça-feira, 19 de junho de 2012 16:07
  • Utilizar Refresh, Dispose, neste caso não ajudaria em nada, certo?

    Certo.

    A idéia é transferir a responsabilidade de processar para outro objeto e apenas alterar o conteúdo do objeto gráfico após o processamento.

    Mantendo os objetos gráficos sempre disponíveis.


    If was useful mark as answered. Mariano, Paulo T. C.


    • Editado ptcmariano quarta-feira, 20 de junho de 2012 12:14
    quarta-feira, 20 de junho de 2012 12:14
  • Assim, faça um teste.

    Crie um for até 30 mil, que cada vez adiciona um botão na tela.

    Apartir do 10 mil, ou 20 mil você não consegue mais adicionar botões na tela, e dai sua tela congela.

    Isso deve estar acontecendo com sua aplicação.  Você deve estar adicionando itens no listbox, até estourar este limite, dai sua aplicação congela.

    Entendeu?


    Quem sabe um dia os DataSets se extinguirão?

    quarta-feira, 20 de junho de 2012 22:47
  • Danimar, ele não cria componentes na tela apenas atualiza as informações.

    Basta separar as regras para outra classe e executar em outra thread para não travar.

    Não faz sentido esse teste que você propôs.


    If was useful mark as answered. Mariano, Paulo T. C.

    quinta-feira, 21 de junho de 2012 15:27
  • Danimar, ele não cria componentes na tela apenas atualiza as informações.

    Basta separar as regras para outra classe e executar em outra thread para não travar.

    Não faz sentido esse teste que você propôs.


    If was useful mark as answered. Mariano, Paulo T. C.

    Ele já está fazendo com thread. Então dizer para fazer com thread também não tem sentido.

    E como o sistema dele vai rodar direto, sem interrupções ele deve tomar o cuidado de limpar os recursos gráficos que ele utiliza, e também memória.

    sexta-feira, 29 de junho de 2012 20:33
  • Antes de atualizar a informação da tela coloque o codigo abaixo. 

    Application.DoEvents(); //faz todo o seu processamento de atualização da tela

    //

    //

    //


    Se resolveu não esqueça de marcar ;)

    sábado, 30 de junho de 2012 00:46
  • Olá,

    Agradeço pela ajuda de vocês, mas até o momento testei todos os procedimentos indicados e não obtive sucesso.

    Realmente não sei o que posso fazer, pois o que percebi é:

    lê 1 e mostra

    lê 2 e mostra

    lê 3, congela e mantém o 2 na tela

    lê 4, continua congelado

    lê 5, descongela e mostra o 3 na tela

    segue normal até congelar novamente.

    Parece que gera uma fila e vai aguardando.

    Usei: Thread, refresh, dispose, ResumeLayout, Application.DoEvents(), e nada resolveu.

    Ainda bem que os inserts no banco de dados acontecem normalmente quando congela, a aplicação não pára, apenas não exibe o que precisa.

    segunda-feira, 2 de julho de 2012 19:26
  • Olha, eu tive o mesmo problema eu sei o Application.DoEvents()  e resolveu.

    No meu caso eu tinha um código que rodava a cada 10 minutos.

    Obs: Você tem que colocar o Application.DoEvents()  uma linha antes de começar a alterar alguma coisa na tela.

    segunda-feira, 2 de julho de 2012 19:52
  • Bom, se você passar um pedaço do código talvez vá ajudar.

    O Application.DoEvents, é válido quando a sua thread executa sem usar sleep, dai não dá tempo de a thread principal efetuar as requisições, então o Application.DoEvents faz com que essas mensagens sejam processadas antes de continuar.

    Como você falou que vc executa de 5 em 5 segundos, não seria esse o caso.

    segunda-feira, 2 de julho de 2012 20:48
  • Olha, o Danimar comentou uma coisa interessante:

    Sim, eu uso thread, mas o meu temporizador não é uma Thread com Sleep e sim um objeto Timer que eu configuro o seu evento Tick pra rodar de 5 em 5 segundos.

    Funciona assim:

    - O Timer inicia

    - Através de uma dll eu verifico se há um registro novo

          - Quando existe, eu dou um stop no Timer e faço o processamento que preciso, e carrego as informações na tela, depois dou Start no Timer para ele voltar a trabalhar.

          - Quando a dll não traz um novo registro o Timer espera 5 segundos e consulta novamente até que exista um novo.

    ......................................................................

    Não sei se deveria usar Thread no lugar do Timer.
    Não sei se poderia acontecer cruzamento de informações ao trabalhar com Thread.
    A Thread que eu uso hoje é apenas na chamada do método "CarregarTela()" com Sleep(100) e com Application.DoEvents() depois da chamada.




    quarta-feira, 4 de julho de 2012 13:03