Ir para conteúdo

POWERED BY:

Arquivado

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

Ranniere Silva

[Resolvido] Utilizando Threads

Recommended Posts

Olá, Já to batendo cartão por aqui.

 

Bem vamos ao problema:

 

Eu tenho um sistema que estou fazendo uma Thread Secundaria para tempos em tempos atualizar o valor de alguns combox e textboxs dessa forma:

 

Dim Thread_RefreshValue As Thread = New Thread(AddressOf RefreshValues)
					Thread_RefreshValue.Start()
obs.: esse código roda em um button no evento click.

 

esse é o componente RefreshValues:

 

Private Sub RefreshValues(ByVal ListFields(,) As String)
		Dim NameField As String = ListFields(0, 0).ToString()
		Dim ValueField As String = ListFields(0, 1).ToString()
		Dim returnValue As Control()
		returnValue = Me.Controls.Find(NameField, True)
		Dim sl As SL_TextBox = returnValue(0) 'SL_TextBox é um usercontrol
		sl.txt.Text = ValueField + 10
	End Sub
obs.: Esse Sub ainda não está completo, por enquanto estou lendo apenas a primeira posição do meu array!

 

 

 

quando eu rodo a aplicação e clico no botão ele gera o erro:

accessed from a thread other than the thread it was created on

 

Pelo que eu procurei eu preciso fazer um delegate da minha thread principal, mas nenhum dos códigos que eu achei eu consegui adaptar para minha aplicação.

 

Qual a saída agora?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá, pensei que tinha resolvido o problema com as Threads mas isso não aconteceu!

vamos ao problema...

 

O que eu achei que tinha resolvido era isso:

 

'Variavel Delegate
Delegate Sub myDelegate()

'Criando minha Thread 
Dim Thread_RefreshValue As Thread = New Thread(AddressOf RefreshValuesMain)

'Esse é o código que resolve o problema do: accessed from a thread other than the thread it was created on

	Private Sub RefreshValuesMain()
		If Me.InvokeRequired Then
			Me.BeginInvoke(New myDelegate(AddressOf RefreshValues))
		End If
	End Sub

'Esse é o Meu Código de Atualizar os valores
 Private Function RefreshValues()
			Dim Address As Short = txtaddress.Text
			For x = 0 To ListFields.GetLength(1) - 1
				Dim NameField As String = ListFields(0, x)
				Dim MapReg As Integer = ListFields(1, x)
				Dim FatorMult As Integer = ListFields(2, x)

				Dim returnValue As Control()
				returnValue = Me.Controls.Find(NameField, True)
				Dim ctr As SL_TextBox = returnValue(0)
				ReturnTry = equipRd(Address, MapReg, 1)
				If ReturnTry = 1 Then
					ctr.txt.Text = equipVar(0) / FatorMult
				Else
					TryRead = TryRead + 1
					Exit For
				End If
			Next

			If TryRead = 3 Then
				btnDesconectar_Click(Nothing, Nothing)
				MsgBox(getMsg("LostConn"), MsgBoxStyle.Critical, titSL)
			End If
	End Function

Enfim ele parou de dar o ERRO! Mas parece que ele Não está criando a segunda Thread, pois se eu coloco um .Sleep() ele para toda a aplicação, e segundo o conceito de multithreads isso não deveria acontecer...

 

Alguém sabe onde eu errei?

Compartilhar este post


Link para o post
Compartilhar em outros sites

Em qual parte do código você colocou o Sleep?

Dentro da minha rotinha de RefreshValues.

Logo após ele terminar a rotina de atualização dos campos.

 

Só que essa parte que parece que ele não cria a segunda Thread tbm reflete sem a ação do .sleep(), por exemplo, eu tenho uma outra rotina que está da mesma forma trocando apenas a função que nesse segundo caso é efetuada quando eu clico em um botão que faz a atualização de valores em um BD e ele para a aplicação inteira e enquanto ele não terminar o ciclo de atualização não consigo efetuar mais nada!

Compartilhar este post


Link para o post
Compartilhar em outros sites

Se voce ver a descrição do evento BeginInvoke você vai entender o que está acontecendo, veja:

"Executes the specified delegate asynchronously with the specified arguments, on the thread that the control's underlying handle was created on".

 

A thread que você criou executa o método RefreshValues na thread que criou ela, ou seja, na principal, pois é ela que tem acesso aos objetos em tela. Por isso quando você usa Thread.Sleep a thread principal fica parada.

 

Pelo que eu entendi você quer executar um processamento e deixar o usuário navegar no aplicativo. Eu vejo de duas maneiras:

1) É um processamento pesado e demorado? criar um windows service e faz sua aplicação windows forms iniciar o serviço.

2) Se for um processamento rápido, você pode usar o método Application.DoEvents(); que vai atualizar a tela, fazendo com que o usuário possa continuar clicando exemplo:

 

for (int i = 0; i < 1000; i++)
{
	Thread.Sleep(1000);
	this.label1.Text = i.ToString();
	Application.DoEvents();
}

Compartilhar este post


Link para o post
Compartilhar em outros sites

Oenning, Bom dia!

 

Eu entendi, mas agora fiquei confuso!

 

Pois tudo que eu li sobre o delegate é que com ele eu consigo acesso aos componentes da thread principal e não a thread em si, ou seja, que as alterações não teriam efeito sobre a thread apenas sobre os componentes que o processo de alteração seria na thread secundaria. Acabei não compreendendo direito o conceito, mas enfim dessa forma que eu pensei existe como fazer?

 

 

Quanto as duas ideias a primeira o meu processo não é tão demora para necessitar de um service, quanto a segunda eu coloquei logo após o sleep da minha thread e ainda assim ele travou a minha aplicação, não deixa eu trabalhar com o resto da aplicação só quando termina o processo.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Temo que não como fazer o que você sugeriu. Faça um teste para ver se a solução que apresentei lhe serve, coloquei um label na tela chamado label1 e coloque o código abaixo no Page_Load. Você vai ver que o label vai ser atualizado de segundo em segundo. Se você remover o DoEvents(), o label só vai ser atualizado no final do processamento, até lá a tela vai ficar bloqueada, que é o que está acontecendo com você.

 

for (int i = 0; i < 1000; i++)
{
	Thread.Sleep(1000);
	this.label1.Text = i.ToString();
	Application.DoEvents();
}

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.