• Revista PROGRAMAR: Já está disponível a edição #53 da revista programar. Faz já o download aqui!

Basic

BackgroundWorker

9 mensagens neste tópico

Boas

tenho um problema que já dei muitas voltas e não consigo encontrar solução para ele  :wallbash:

se calhar a solução é muito básica mas já to tão a nora que não encontro

  • Tenho uma classe principal Window1 com um form;
  • Preciso que outra classe possa aceder a uma funçao da Window1 para escrever numa caixa de texto desse mesmo form.

Mas a classe Window1 chama a outra classe dentro de um backgroundworker...

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

os eventos ProgressChanged e RunWorkerCompleted correm no contexto da thread de UI (user interface), só podes mudar UI através deles, no DoWork não podes.

no DoWork afecta o e.Result com o texto que queres lá meter e depois no RunWorkerCompleted já o podes usar para mudar o texto da textbox

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

;)

eu tenho uma função que inicializa o thread e chama a outra class, no entanto eu preciso que enquanto a segunda class está a correr que vá enviando strings para a textbox

private void Start_Click(object sender, RoutedEventArgs e)

{

      Process proc = new Process();

      _worker.WorkerReportsProgress = true;

      _worker.DoWork += delegate(object s, DoWorkEventArgs args)

        {

                BackgroundWorker worker = s as BackgroundWorker;

                proc.connect();

                if (worker.CancellationPending)

                {

                    args.Cancel = true;

                    return;

                }

            };

...

}

o meu problema é que não sei como fazer com que a class Process possa escrever na textbox, já experimentei utilizando delegate no entanto recebo a mensagem "O thread de chamada não pode aceder a este objecto porque existe outro thread que já o tem."

               

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

"O thread de chamada não pode aceder a este objecto porque existe outro thread que já o tem." Ou seja, só a thread que criou o controlo gráfico é que pode mudar o estado desse controlo. Como já disse, dentro do DoWork isso não é possível, apenas dentro dos outros 2 eventos que enunciei.

podes usar o método worker.ReportProgress(percentComplete); para reportar progresso, ou seja, disparar o evento ProgressChanged

podes, à semelhança do que fizeste para o DoWork, registar um delegate no ProgressChanged e nesse evento já podes mudar o texto da textbox porque esse evento já corre na thread que criou o controlo gráfico e não na thread de "background"

no DoWork vais enviando strings com o reportProgess e no ProgressChanged vais afectando o controlo, percebeste?

erro meu, o método reportProgress só recebe um valor inteiro :s

tens pelo menos 2 hipóteses, lançar vários backgroundworkers de modo a ir recebendo várias mensagens ou, se possível,  criar um esquema em que o inteiro passado no ReportProgress signifique que é para mostrar a mensagem X

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

hummm

to a ver que isto afinal é muito mais complicado doque parecia  ;)

e assim não to a ver muito bem como posso fazer, pois preciso que a UI não fique bloqueado enquanto estou a correr as funções na segunda class no entanto tenho que fazer com que a textbox receba as strings, e se o reportProgress apenas recebe int não ajuda muito  :down:

por exemplo na segunda class preciso ter uma coisa genro

private void connect()

{

      for(int i=0; i<200;i++)

      {

              textbox.Text = "ai "+i;

      }

}

em que seja possível criar uma string e poder escreve la na texbox

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

pois, não sei se foi só exemplo mas isso é má programação

string é um objecto imutável, cada vez que fazes uma concatenação (string+string) ele cria um novo objecto para alojar essa concatenação! muito mau!

usa antes um StringBuilder (google it)

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

ah, em relação ao teu problema, terá que ser um backgroundWorker para cada função que queres correr (para as funções que podem demorar tempo a correr)

estás a usar visual studio? criar isso no visual studio é muito rápido!

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Tenta assim:

private void connect()

{

      textBox1.Invoke(new EventHandler(ActualizarTextBox)); // textBox1 é a caixa que queres afectar

}

private void ActualizarTextBox(object sender, EventArgs e)

{

            TextBox tb = sender as TextBox;

            if (tb != null)

            {

                  string s; // ou stringBuilder para ficar como deve ser

                  for(int i=0; i<200;i++)

                  {

                          s = "ai "+i; // adaptar tb p o stringbuilder

                  }

                    tb.Text = s;

          }

}

0

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!


Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.


Entrar Agora