Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Alexandre Carmo

Aplicativo com Thread

Recommended Posts

Boa tarde

Preciso desenvolver um projeto onde terá o uso ao mesmo tempo de alguns aparelhos de código de barras, Minha aplicação vai acessar esse aparelho e tratar ela e envia para o banco de dados (ou seja minha aplicação tem que ficar acessando o aparelho constantemente para saber se tem dados), a parte complexa é que serão 7 aparelhos funcionando ao mesmo tempo, então acredito que para isso eu tenha que trabalhar com threads (já tenho o domíni completo do aparelho mas usando um por vez). Porém gostaria de sugestão de qual a melhor de fazer esse trabalho. Tem outra coisa importante o aplicativo que recebe a informação estara executando outras tarefas ou seja essa opção que trabalha com os aparelhos terá que ficar funcionando em segundo plano, essa parte do segundo plano não tenho idéia de como funciona se alguém tiver como me explicar fico grato também.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alexandre,

 

Caso você esteja usando VB.NET o exemplo a seguir pode te ajudar:

Pra executar o exemplo, crie um projeto Windows do tipo Console e no Module1.vb coloque o seguinte:


Imports System.Threading
Module Module1

    Sub Main()
        Dim _Thread1 As New Thread(AddressOf MetodoPersonalizado1)
        Dim _Thread2 As New Thread(AddressOf MetodoPersonalizado2)
        _Thread1.Start()
        _Thread2.Start()
        Console.ReadLine()
    End Sub
    Sub MetodoPersonalizado1()
        While True
            Console.WriteLine("Método acionado pela thread 1")
            Thread.Sleep(5000)
        End While
    End Sub
    Sub MetodoPersonalizado2()
        While True
            Console.WriteLine("Método acionado pela thread 2")
            Thread.Sleep(2000)
        End While
    End Sub
End Module

O mesmo código acima em C#:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Thread
{
    class Program
    {
        static void Main(string[] args)
        {
            System.Threading.Thread _Thread1 = new System.Threading.Thread(new ThreadStart(MetodoPersonalizado1));
            System.Threading.Thread _Thread2 = new System.Threading.Thread(new ThreadStart(MetodoPersonalizado2));
            _Thread1.Start();
            _Thread2.Start();
            Console.ReadLine();
        }
        static void MetodoPersonalizado1()
        {
            while (true)
            {
                Console.WriteLine("Método acionado pela thread 1");
                System.Threading.Thread.Sleep(5000);
            }
        }
        static void MetodoPersonalizado2()
        {
            while (true)
            {
                Console.WriteLine("Método acionado pela thread 2");
                System.Threading.Thread.Sleep(2000);
            }
        }
    }
}

Os exemplos acima são bem simples, mas totalmente funcionais, eles implementam o conceito de Multi-threading que é o que você precisa.

Pra rodar em segundo plano aconselho que crie sua aplicação na forma de windows service, qualquer coisa conte com minha ajuda.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Pedro

Então estudei alguns tutoriais na net e consegui montar uns exemplos, testei o seu também e acredito que entendi, agora é o seguinte estou desenvolvendo uma aplicação desktop com vb.net e criei um teste que vai carregar um aparelho com sensor e toda vez que alguém colocar o dedo no sensor ele vai mandar a imagem para minha tela, criei uma thread para isso com delegade e funcionou, porém o form contém outras opções que tem que estar funcionando ao mesmo tempo, essas opções não carregam direito ou simplesmente não carregam, a thread tem que ficar rodando sem atrapalhar os demais componentes do form. Como eu posso corrigir isso para funcionar tudo normalmente no meu form? Os botões que tenho no meu form não carregam e a idéia é usar esses botões enquanto o evento da thread fica rodando também, tem uma webcam por exemplo que ao clicar em um botão ela vai carregar também mas o botão nem aparece na tela. A única coisa que esta funcionando é a thread. Ela tem que ficar funcionando sozinha como esta mas sem atrapalhar os demais trabalhos do form.

Veja como fiz?

Private t1 As Thread
  Public Sub prenchelista1()

    While True
       Me.Invoke(New AddItemsDelegate(AddressOf Sensor))
    End While
  End Sub

   Private Delegate Sub AddItemsDelegate()
  Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    ConectaF7()
    t1 = New Thread(AddressOf Me.prenchelista1)
    t1.Start()

  End Sub

...
Private Sub Sensor()

    Dim width As Integer
    Dim height As Integer
    Dim image As Byte()
    Dim b_dedo As Bitmap

    ldTest.SensorGetImage(New TimeSpan(0, 1, 0), width, height, image)
    If image IsNot Nothing Then
      Dim mk_bmp As New MakeBitmap()
      mk_bmp.MakeBitmapMy(width, height, image, b_dedo)
      PictureBox1.Size = New Size(width, height)
      Dim resolution As Integer = 500
      
myUtil.raw.height = height
      myUtil.raw.width = width
      myUtil.raw.res = resolution
      myUtil.raw.img = FingerPrintToBytes(b_dedo)


      '' display fingerprint image
      myUtil.PrintBiometricDisplay(False, GRConstants.GR_DEFAULT_CONTEXT)

      Extract()

    End If
  End Sub

Compartilhar este post


Link para o post
Compartilhar em outros sites

Que bom que te ajudou de alguma forma.

 

Nunca me deparei com uma situação como essa, tentei montar um ambiente de simulação a fim de reproduzir um cenário como esse, criei uma aplicação desktop com 2 threads independentes da ação do usuário e um botão acionado pelo usuário a qualquer momento, funcionou conforme esperado.

 

Olhando seu código percebi que você não silencia sua thread, é possível que ajude a resolver o problema alterando o seguinte código:


Public Sub prenchelista1()

    While True
   	Me.Invoke(New AddItemsDelegate(AddressOf Sensor))
   	Thread.Sleep(1000) 'Isso silencia a thread por um segundo
    End While
End Sub

 

Além disso, coloque no Load do seu formulário a seguinte linha:

CheckForIllegalCrossThreadCalls = False

 

Se quiser, disponibilizei o código fonte do teste que fiz aqui: Código Fonte

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Pedro, valeu por mais essa

 

Entedi o que vocÊ informou, busquei informações e entendi o sleep, velho realmente deu uma diferença os thread rolou legal. Porém cara agora estou com o problema que é justamente na minha sub Sensor quando ela entra em ação ela trava todo meu formulário até que ela seja finalizada, esse é o problema final agora, preciso que as coisas continuem funcionando enquanto ela trabalha. Esse função do sensor funcina da seguinte forma, quando ela é chamado ela vai acessar um aparelho capturar uma imagem e mandar para o form, enquanto o aparelho não recebe esse imagem para enviar, a sub Sensor esta travando o meu form e não consigo fazer nada mesmo sendo uma thread em ação. VocÊ tem idéia de como posso resolver isso?

Vou postar o código que trabalha com a sub Sensor:

Private ldTest As Neurotec.Scanner.FingerCell.LanDevice '' carrega o scanner f7
Private Sub Sensor()

        Dim width As Integer
        Dim height As Integer
        Dim image As Byte()
        Dim b_dedo As Bitmap

        Application.DoEvents()
        ldTest.SensorGetImage(New TimeSpan(0, 1, 0), width, height, image)
        Application.DoEvents()
        If image IsNot Nothing Then
            Dim mk_bmp As New MakeBitmap()
            mk_bmp.MakeBitmapMy(width, height, image, b_dedo)
            PictureBox1.Size = New Size(width, height)
            Dim resolution As Integer = 500

            myUtil.raw.height = height
            myUtil.raw.width = width
            myUtil.raw.res = resolution
            myUtil.raw.img = FingerPrintToBytes(b_dedo)


            '' display fingerprint image
            myUtil.PrintBiometricDisplay(False, GRConstants.GR_DEFAULT_CONTEXT)

            
        End If
    End Sub

Essa á a parte que vai acessar o scanner:

ldTest.SensorGetImage(New TimeSpan(0, 1, 0), width, height, image)

E essa condição aguarda o resultado:

If image IsNot Nothing Then ....

Enquanto isso não ocorre o sistema fica aguardando a resposta porém preciso que as demais partes cotinuem funcionando. O que você acha tem alguma idéia?

Valeu pela força

Compartilhar este post


Link para o post
Compartilhar em outros sites

Alexandre,

 

Você já tentou colocar essa Sub em uma Thread também? Ao invés de chamar a Sub diretamente instancie ela numa Thread e dê start, assim:

 

Na chamada da Sub:

Dim _ThreadSensor as New Thread(AddressOf Sensor)
_ThreadSensor.Start()

 

No código da sub tire o primeiro Application.DoEvents() e substitua o segundo por Thread.Sleep(500), isso representa uma pausa de meio segundo, você pode aumentar ou diminuir conforme sua necessidade.

 

Colocando a Sub Sensor em uma thread acredito que pare de travar seu form.

 

Se não der certo fala aí que a gente pensa em outra coisa.

 

Abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Opa beleza Pedro

 

Então velho fiz o teste e não rolo na verdade não teve efeito nenhum, acredito que como a sub Sensor já é chamada por uma thread o problema não seria esse. Vou continuar quebrando a cabeça aqui velho se eu achar uma solução vou postar se você tiver alguma idéia posta aí por favor.

Compartilhar este post


Link para o post
Compartilhar em outros sites

É verdade, analisando de novo seu código percebi que não faria diferença mesmo.

 

Me diz uma coisa, você não pode separar essa funcionalidade de verificação do scanner em uma aplicação específica pra isso, ou seja, que não precise fazer outras coisas? Dessa forma você poderia criar uma aplicação do tipo Windows Service (posso te ajudar se for o caso) rodando em segundo plano, enquanto sua aplicação Windows Forms faz o restante que precisa ser feito. Tem essa possibilidade?

 

É verdade, analisando de novo seu código percebi que não faria diferença mesmo.

 

Me diz uma coisa, você não pode separar essa funcionalidade de verificação do scanner em uma aplicação específica pra isso, ou seja, que não precise fazer outras coisas? Dessa forma você poderia criar uma aplicação do tipo Windows Service (posso te ajudar se for o caso) rodando em segundo plano, enquanto sua aplicação Windows Forms faz o restante que precisa ser feito. Isso te facilitaria no futuro também pensando em manutenção ou se um dia trocasse de marca de scanner precisaria mudar apenas essa aplicação específica. O que acha?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Pedro

 

Cara essa idéia que vocÊ passou seria ótimo velho, Como nós faríamos? Além de resolver meu problema vai me ensinar algo novo. A idéia de ficar rodando em segundo plano enquanto meu form roda as outras coisa é perfeita.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Então, criar um Windows Service é mais simples do que parece, porém precisa ter atenção com algumas coisas.

 

Primeiro, com um Windows Service não é possível interagir de forma visual, portanto se acontecer algum erro não será possível disparar um msgox com o erro, tem que ter um tratamento de erro bem estruturado e aconselho usar o próprio Event Viewer pra gerar os logs da aplicação, se você nunca usou o Event Viewer eu te ajudo, é bem tranquilo.

 

Vamos ao que interessa:

 

1 - Crie um novo projeto do tipo Windows Service

 

Já faça algumas configurações tais como:

 

a: Mudar o nome do arquivo Service1.vb para o nome da sua aplicação

b: Clique com o botão direito no arquivo que acabou de renomear e escolha a opção View Designer

c: Vá em Properties e configure AutoLog = True

Isso fará com que o serviço escreva no event viewer da máquina sempre que seu serviço iniciar e parar

d: Mude o valor da propriedade ServiceName para o nome que você queira que apareça no Gerenciador de Serviços, normalmente um nome que identifique o que é e o que faz

e: Clique novamente com o botão direito no arquivo "Nome".vb e escolha View Code e você verá dois métodos: onstart e onstop, não mudaremos nada por enquanto

f: Escreva seus códigos nesse arquivo, ou se quiser, crie novas classes e módulos conforme sua necessidade

g: No método onstart faça a chamada para o que deve acontecer assim que o serviço for iniciado

h: No método onstop faça a chamada para o que deve acontecer assim que o serviço for parado, limpar variáveis, etc

 

Feito isso precisamos criar um instalador para o serviço, é bem simples:

 

a: Vá para o Designer (passo b: do ítem anterior)

b: Clique com o botão direito na área cinza e escolha a opção: Add Installer

Aparecerá um novo arquivo, ProjectInstaller.vb com dois objetos: ServiceProcessInstaller1 e ServiceInstaller1

c: Clique no ServiceProcessInstaller1 e vá em propriedades e configure com qual Account o serviço deve ser iniciado, eu normalmente uso LocalSystem

d: Clique agora no ServiceInstaller1 e vá em propriedades e configure a Description (descrição do seu serviço, aparecerá no gerenciador de serviços), configure também DisplayName que é o nome a ser exibido no gerenciador de serviços, na propriedade StartType fica se o serviço inicia de forma manual ou automática, se deixar como manual sempre terá que iniciar o serviço quando o Windows iniciar, se deixar automático o próprio Windows faz isso por você.

 

Agora com tudo escrito e configurado, vamos instalar o serviço:

 

a: Compile seu projeto e vá até a pasta bin, dentro dela terá a pasta Debug se você compilou em modo debug e a pasta Release se você compilou em modo Release, use sempre o modo Release para colocar em produção

b: abra o prompt de comando do visual studio, normalmente na pasta do Visual Studio Tools na pasta Microsoft Visual Studio 200x em Todos os Programas

c: no prompt, navegue até o diretório onde está o .exe compilado e digite o seguinte:

installutil NomeDoPrograma.exe

Será executado uma série de passos, assim que terminar abra o gerenciador de serviços e veja se o seu está lá

d: abra o Event Viewer e vá na opção Aplicativo

e: caso não tenha iniciado o serviço de forma automatica, inicie agora e veja se aparece no Event Viewer o log do seu serviço dizendo que o serviço iniciou com sucesso. aperte F5 no Event Viewer pra atualizar se não aparecer nada

 

Faça isso e me diga se deu certo, qualquer dúvida me fale que tento te ajudar.

 

Abraço

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Pedro

Velho desculpa a demora, tive alguns problemas ontém no trabalho não consegui continuar os testes

Estou testando o que você passou porém não estou conseguindo instalar, estou usando o visual studio 2010, entrei no prompt de comando do dos fui até a pasta do arquivo executável mas não rolo, ele me deu a seguinte mensagem de erro:

'installutil' não é reconhecido como um comando interno

ou externo, um programa operável ou um arquivo em lotes.

 

Essa é a única forma de instalar e executar? Teria outra forma? Por exemplo quando crio uma aplicação windows uso o innosetup para fazer o instalador, será que não tem como criar um instalador visual? Outra pergunta esse tipo de aplicação acessa banco de dados normalmente?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Pedro

Correção confundi as coisas consegui achar o installUtil esta na pasta do framework pensei que ele vinha com o windows

Fica então só a dúvida:

Essa é a única forma de instalar e executar? Teria outra forma? Por exemplo quando crio uma aplicação windows uso o innosetup para fazer o instalador, será que não tem como criar um instalador visual? Outra pergunta esse tipo de aplicação acessa banco de dados normalmente?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Boa tarde Pedro

Correção confundi as coisas consegui achar o installUtil esta na pasta do framework pensei que ele vinha com o windows

Fica então só a dúvida:

Essa é a única forma de instalar e executar? Teria outra forma? Por exemplo quando crio uma aplicação windows uso o innosetup para fazer o instalador, será que não tem como criar um instalador visual? Outra pergunta esse tipo de aplicação acessa banco de dados normalmente?

 

Opa, vamos lá:

 

Dúvida 1: Essa é a única forma de instalar e executar? Teria outra forma? Por exemplo quando crio uma aplicação windows uso o innosetup para fazer o instalador, será que não tem como criar um instalador visual?

 

Dá pra criar um instalador visual sim com o próprio visual studio, há um tipo de projeto: Setup and Deployment, te falei do installUtil pois é mais rápido e pra testar não precisaria criar um instalador completo. Eu nunca usei o innosetup, sempre crio um projeto de instalação para meus sistemas, não sei se é possível usar o innosetup para instalar um Windows Service, provavelmente sim, se você quiser criar um projeto de instalação com o Visual Studio e não souber como, posso te ajudar, mas se conseguir usar o innosetup beleza.

 

Dúvida 2: esse tipo de aplicação acessa banco de dados normalmente?

Acessa sim, a única restrição desse tipo de aplicação é que não se pode usar nenhum recurso visual, já que ele é um serviço.

 

Acredito que conseguiu criar o serviço e executar o que precisava, certo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Pedro

Cara obrigado por mais essa ajuda

Na verdade eu só fiz teste de uso, ainda não coloquei o que eu preciso, vou começar a testar isso hoje e se eu consegui vou postar aqui para servir para a galera que precisar.

Nunca criei o instalador pelo visual studio, se você tiver como me ajudar a criar um instalador pelo Visual Studio seria muito bom.

Outra dúvida após eu instalar o projeto com o instalador criado pelo visual studio ele já inicia o processo?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom dia Pedro

Cara obrigado por mais essa ajuda

Na verdade eu só fiz teste de uso, ainda não coloquei o que eu preciso, vou começar a testar isso hoje e se eu consegui vou postar aqui para servir para a galera que precisar.

Nunca criei o instalador pelo visual studio, se você tiver como me ajudar a criar um instalador pelo Visual Studio seria muito bom.

Outra dúvida após eu instalar o projeto com o instalador criado pelo visual studio ele já inicia o processo?

 

Sempre que precisar e eu souber ajudar conte comigo.

 

Com relação ao projeto de instalação com Visual Studio, é bem tranquilo, vou montar um tutorial e te passo.

 

Assim que você instala o serviço ele obedece a sua configuração, se colocou pra Startup automático ele inicia sozinho, se colocou pra Startup manual você mesmo terá que iniciá-lo.

 

Abraço.

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.