none
Threads ??? RRS feed

  • Pergunta

  • Pessoal ... tenho uma aplicação que devera realizar sete processamentos em paralelo então terei que usar threads ja ate post uma outra vez aqui no forum mas ainda não obtive exito ... eu gostaria de uma dica e tabmém tirar uma duvida

    Tenho o seguinte cenario:
    Terei que montar sete blocos de codigo ou seja sete metodos do tipo void pois pelo que andei vendo threads tem que ser tipo void, o codigo seria assim

    private void bloco01()
    {
        string SQL = "Select Campo1 Tabela";
        < comandos ... >
        While ( ...... )
        {
             SQL = Insert Into Tabela (....) Values (.....)
       
        }
    }

    Por exemplo terei sete metodo como acima cada um fazendo sua respectiva carga como posso montar um esquema de tjhreads para gerenciar isso pois pelo que andei vendo não consigo atualizar um objeto de tela usando dentro de um metodo desses por exemplo um textobox com um contador de registros para que o usuario se oriente na tela ...
    Bom resumindo como poderia fazer um codigo usando threads que gerencie meus sete blocos de codigo

    Vlwwww
    Junior
    sábado, 26 de dezembro de 2009 15:25

Todas as Respostas

  • Se eu entedi vc quer retornar um valor da thread para a tela... vc pode fazer isso com eventos ou com o invoke...

    public class MyClass {
        public event EventHandler QueryExecuted;

        protected virtual void OnQueryExecuted() {
             if (this.QueryExexuted != null) this.QueryExecuted(this, new EventArgs());
        }

        public void Start() {
            new Thread(new ThreadStart(Bloco01)).Start();
            new Thread(new ThreadStart(Bloco02)).Start();
            new Thread(new ThreadStart(Bloco03)).Start();
            new Thread(new ThreadStart(Bloco04)).Start();
        }

        private void Bloco01() {
              string SQL = "Select Campo1 Tabela";
              < comandos ... >
              While ( ...... )   {
                      SQL = Insert Into Tabela (....) Values (.....)
                      this.OnQueryExecuted();
              }
        }
    }



    public class Form1: Form {
          private int QCount = 0;

          private void Executar()  {
              var blocos = new MyClass();
              blocos.QueryExecuted = delegate(object sender, EventArgs e) {
                   QCount++;
                    Textbox1.text = QCount.ToString();
              };
              blocos.Start();
          }
    }
    What would Brian Boitano do ? ((2B || !2B) is Question) ?
    sábado, 26 de dezembro de 2009 17:08
    Moderador
  • Ola
    Rui é mais ou menos assim

    Eu terei sete processamentos em paralelo então terei sete metodos

    private void Bloco01()
    {
       string SQL = "Select Campo1 Tabela";
       < comandos ... >
       While ( ...... )  
        {
            SQL = Insert Into Tabela (....) Values (.....)
            Text1box1.Text = contador ++; 
        }
    }

    Então terei sete blocos de comando como acima com sete textbox na tela onde em cada um os metodos chamados bloco atualizarão o valor do contador, eu dei uma olhada no codigo que você postou mas não consegui entender muito bem o porque dos eventos, teria alguma solução mais simples pois não tenho muita intimidade ainda com certos processos da lingiuagem (desculpa a ignorancia rssss)
    E também aproveitar para perguntar porque quando inserimos um objeto tipo um textbox dentro de um metodo e a thread vai executar ela gera erro ele não aceita usar objetos nos metodos usados dentro de threads ou terie que usar o codigo para isso cmo você m mostrou no post

    Vlw Abraço

    Junior
    domingo, 27 de dezembro de 2009 10:48
  • entao... ao 7 eventos eu coloquei 4 ... mas eh so continuar

    public void Start() {
            new Thread(new ThreadStart(Bloco01)).Start();
            new Thread(new ThreadStart(Bloco02)).Start();
            new Thread(new ThreadStart(Bloco03)).Start();
            new Thread(new ThreadStart(Bloco04)).Start();
            new Thread(new ThreadStart(Bloco05)).Start();
            new Thread(new ThreadStart(Bloco06)).Start();
            new Thread(new ThreadStart(Bloco07)).Start();
    }

    sobre o erro de acessar o TextBox dentro de uma thread diferente.... isso não ocorre... pq o evento eh disparado na mesma thread que criou o TextBox....

    em cada bloco vc chama o medoto this.OnQueryExecuted(); que vai disparar o evento....

    talves eu tenha te confundido pq usei a forma resumida de execusao do evento no formulario

    public class Form1: Form {
          private int QCount = 0;
          private MyClass blocos = new MyClass();
              
          private void Executar()  {         
              blocos.QueryExecuted += blocos_QueryExecuted;
              blocos.Start();
          }

          private void blocos_QueryExecuted(object sender, EventArgs e) {
                   QCount++;
                    Textbox1.text = QCount.ToString();
          };
    }


    Ah ideia é:

    1- Crie uma classe para efetuar o processamento em paralelo dos seus blocos
    2- Crie um metodo de inicialização da Threands (public void Start)
    3- Crie um evento para informar ao formulario que uma query foi executada (QueryExecuted)
    4- Crie um metodo para execução do metodo criado acima (OnQueryExecuted)
    5- Nos blocos de 1 a 7 apos a execução da query vc chama o metodo de execução da query acima citado
    6- No seu formulario vc cria uma nova instancia da classe acima criada "private MyClass blocos = new MyClass();"
    7- Defina um metodo para o evento de execução da query "blocos_QueryExecuted"
    8- Atribuir o metodo criado acima ao evento "blocos.QueryExecuted += blocos_QueryExecuted;"
    9- Iniciar o processo (blocos.Start();)

    Como o metodo "blocos_QueryExecuted" esta na mesma thread de criação do TextBox... não deveria ocorre erro ao setar o valor da propriedade Text... mas caso ocorra da uma pesquisada pelo metodo Invoke

    What would Brian Boitano do ? ((2B || !2B) is Question) ?
    segunda-feira, 28 de dezembro de 2009 12:00
    Moderador
  • É exatamente o que o Rui falou, você precisara criar uma thread e dentro da thread lançar eventos ou simplesmente chamar métodos. Você necessita fazer a verificação de InvokeRequired do objeto que você está tentando acessar pois os objetos de formulário são criados na Thread principal, é só ela que atualiza e desenha os objetos, e chamando o método Invoke ou beginInvoke você está "pedindo" para a thread principal executar o código para você.
    Caso contrário receberá: "O acessado de um thread não é aquele na qual foi criado"
    public sub AtualizarProgress(byval i as integer)
       if progress.InvokeRequired then
           progress.BeginInvoke(new Action(of Integer)(addressof AtualizarProgress), i)
           return 
       end if
       progress.value = i
    end sub
    
    
    private sub MinhaThread()
    
    AtualizarProgress(1)  // Isso não vai dar erro
    
    progress.value = 1 //Isso vai dar erro.
    
    end sub

    Como você vai criar varias threads seria legal usar a classe ThreadPool, que produz melhor performance, e tambem chamar o método BeginInvoke() ao invéz de Invoke() nos objetos de formulario.

    Ao invéz de utilizar 7 métodos diferentes não teria como criar apenas um método e passar como parametro?
    No método start da thread é possivel passar parametros para a thread.
    terça-feira, 29 de dezembro de 2009 18:16