CARREGANDO EM SEGUNDO PLANO
E o que eu teria que fazer?
Para atualizar um controle à partir de uma thread? Eu desaconselho totalmente fazer isso, mas é possÃvel. No seu form, você cria um método que faz o que você quiser, atualiza grid, progressbar... enfim o que quiser, inclusive recebendo parâmetros se quiser. Então use o método Invoke à partir da sua outra thread:
Mas novamente, frisando muito bem: ISSO é UMA PéSSIMA PRÃTICA. Serve para quebrar um galho, mas de maneira nenhuma deve-se usar isso.
SeuForm.Invoke(() => SeuForm.SeuMetodo(parametro1, parametro2, ...));
Mas novamente, frisando muito bem: ISSO é UMA PéSSIMA PRÃTICA. Serve para quebrar um galho, mas de maneira nenhuma deve-se usar isso.
tentei assim pelo Macorrat:
também tentei
Form1.DataGridView2.DataSource.Invoke(result)
- Variável de objeto ou variável com bloco não definida.também tentei
Form1.invoke(Form1.DataGridView2.DataSource = Result)
- O operador [ô]=[ô] não está definido para [ô]Nothing[ô] e tipo [ô]List(Of Clientes)[ô]. Form1.Invoke(Function() Form1.DataGridView2.DataSource = result)
- Não é possÃvel chamar Invoke ou BeginInvoke em um controle antes da criação do identificador de janela.
O que você está fazendo que precisa tanto assim de threads?
Vou te passar um código que deve fazer aquilo que vc quer
esse código lê um arquivo do tipo texto e atualiza os registros de uma tabela no banco de dados, ao mesmo tempo vai atualizando um progreassbar na tela
Delegate Sub DownloadCompletoSafe(ByVal cancelled As Boolean) [ô]Estudar
Delegate Sub AlterarTextosSafe(ByVal Length As Long, ByVal Position As Integer, ByVal Percent As Integer, ByVal Speed As Double)
Delegate Sub InicializarProgressBar(ByVal Valor As Long)
Delegate Sub AtualizarProgressBar(ByVal Valor As Long)
Delegate Sub AtualizacaoCompleta()
Delegate Sub IniciarDownload()
Private Sub TarefaCompleta()
Pgb.Visible = False
PicCerto2.Location = New Point(Label5.Left - PicCerto2.Width, Label5.Top + (Label5.Height - PicCerto2.Height) / 2)
PicCerto2.Visible = True
PicSeta3.Visible = False
Label8.Visible = False
BtnAtualiza.Enabled = True
BtnFechar.Enabled = True
End Sub
Private Sub InicializaProgressBar(ByVal Valor As Long)
Pgb.Maximum = Valor
Label5.Visible = True
Pgb.Location = New Point(Label5.Left, Label5.Bottom)
Pgb.Visible = True
PicSeta3.Location = New Point(Label5.Left - PicSeta3.Width, Label5.Top + Label5.Height / 2 - PicSeta3.Height / 2)
PicSeta3.Visible = True
Label8.Visible = True
End Sub
Private Sub AtualizaProgressBar(Valor As Long)
Pgb.Value = Valor
Label8.Text = FormatPercent(Valor / Pgb.Maximum, 0)
End Sub
Private Sub DownloadComplete(ByVal Cancelar As Boolean)
PicSeta2.Visible = False
Label9.Visible = False
PicCerto3.Location = New Point(Label4.Left - PicCerto3.Width, Label4.Top + (Label4.Height - PicCerto3.Height) / 2)
PicCerto3.Visible = True
Pgb.Value = 0
Pgb.Visible = False
End Sub
Private Sub IniciaDownload()
Label4.Visible = True
Label9.Visible = True
PicSeta2.Location = New Point(Label4.Left - PicSeta2.Width, Label4.Top + (Label4.Height - PicSeta2.Height) / 2)
PicSeta2.Visible = True
Pgb.Value = 0
Pgb.Location = New Point(Label4.Left, Label4.Bottom)
Pgb.Visible = True
End Sub
Private Sub AlterarTextos(ByVal Length As Long, ByVal Pos As Integer, ByVal percent As Integer, ByVal Tempo As Double)
Pgb.Maximum = Length
Pgb.Value = Pos
Label9.Text = Math.Round((Pos / 1024), 2) & [Ô] KB de [Ô] & Math.Round((Length / 1024), 2) & [Ô]KB ([Ô] & Pgb.Value & [Ô] %)[Ô]
If Tempo = 0 Then
Label9.Text = [Ô]Calculando...[Ô]
Else
Label9.Text = Math.Round((Tempo / 1024), 2) & [Ô] KB/s[Ô]
End If
[ô]Pgb.Value = percent
End Sub
Private Sub BakWork_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BakWork.DoWork
Dim NR As New System.Text.RegularExpressions.Regex([Ô]
[Ô])
Dim Arq As New System.IO.StreamReader(NomeArq)
Dim St As String = Arq.ReadToEnd()
Arq.Close()
Arq.Dispose()
Arq = New System.IO.StreamReader(NomeArq)
Dim Qtd As Long = NR.Matches(St).Count + 1
Dim AtualPGB As New InicializarProgressBar(AddressOf InicializaProgressBar)
Me.Invoke(AtualPGB, Qtd)
Try
Using ConDB As SqlConnection = New SqlConnection(PDns)
ConDB.Open()
Dim Posi As Long = 0
Dim Txt As String = [Ô][Ô]
Dim L As Integer = 0
Using RstCmd As SqlCommand = New SqlCommand([Ô]Select Col_Length([ô]NCMS[ô], [ô]Nome[ô])[Ô], ConDB)
L = RstCmd.ExecuteScalar
End Using
Do
Posi += 1
Txt = Arq.ReadLine
If Posi > 1 AndAlso Not Txt Is Nothing Then
Dim A() As String = Txt.Split([Ô];[Ô])
If Val(A(2)) = 0 Then
Dim Crit As String = [Ô]Update TabelaIBPT SET Tabela = 0,IbpEx = [ô][Ô] & A(1) & [Ô][ô],AliqNac = [Ô] & A(4) & [Ô], AliqImp = [Ô] & A(5) & [Ô], AliqEst = [Ô] & A(6) & [Ô],AliqMun = [Ô]
Crit += A(7) & [Ô], DiaIni = [ô][Ô] & A(8) & [Ô][ô], DiaFim = [ô][Ô] & A(9) & [Ô][ô],Chave = [ô][Ô] & A(10) & [Ô][ô],Versao = [ô][Ô] & A(11) & [Ô][ô],Fonte = [ô][Ô] & A(12) & [Ô][ô] where Ncms = [ô][Ô] & A(0)
Crit += [Ô][ô] IF @@ROWCOUNT = 0 [Ô]
Crit += [Ô]Insert Into TabelaIBPT(NCMS, Tabela, IbpEx, AliqNac, AliqImp, AliqEst, AliqMun, DiaIni, DiaFim, Chave,Versao, Fonte) VALUES([ô][Ô] & A(0).Trim & [Ô][ô], 0,[ô][Ô]
Crit += A(1).Trim & [Ô][ô],[Ô] & A(4) & [Ô],[Ô] & A(5) & [Ô],[Ô] & A(6) & [Ô],[Ô] & A(7) & [Ô],[ô][Ô] & A(8) & [Ô][ô],[ô][Ô] & A(9) & [Ô][ô],[ô][Ô] & A(10) & [Ô][ô],[ô][Ô] & A(11) & [Ô][ô],[ô][Ô] & A(12) & [Ô][ô])[Ô]
Using RstCmd As SqlCommand = New SqlCommand(Crit, ConDB)
RstCmd.ExecuteNonQuery()
End Using
A(3) = Strings.Left(A(3), L)
Crit = [Ô]Update NCMS Set Nome = [ô][Ô] & A(3) & [Ô][ô] where Ncms = [ô][Ô] & A(0).Trim & [Ô][ô] [Ô]
Crit += [Ô]IF @@ROWCOUNT = 0 [Ô]
Crit += [Ô]Insert Into NCMS(NCMS, Nome) Values([ô][Ô] & A(0).Trim & [Ô][ô],[ô][Ô] & A(3).Trim & [Ô][ô])[Ô]
Using RstCmd As SqlCommand = New SqlCommand(Crit, ConDB)
RstCmd.ExecuteNonQuery()
End Using
End If
End If
Dim PosiPgb As New AtualizarProgressBar(AddressOf AtualizaProgressBar)
Me.Invoke(PosiPgb, Posi)
Loop Until Txt Is Nothing
End Using
Arq.Close()
Arq.Dispose()
Dim Compl As New AtualizacaoCompleta(AddressOf TarefaCompleta)
Me.Invoke(Compl)
Catch ex As Exception
Arq.Close()
Arq.Dispose()
MessageBox.Show(ex.Message, [Ô]Atualização IBPT[Ô], MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
A figura anexa mostra a tela que é alimentada pela rotina
esse código lê um arquivo do tipo texto e atualiza os registros de uma tabela no banco de dados, ao mesmo tempo vai atualizando um progreassbar na tela
Delegate Sub DownloadCompletoSafe(ByVal cancelled As Boolean) [ô]Estudar
Delegate Sub AlterarTextosSafe(ByVal Length As Long, ByVal Position As Integer, ByVal Percent As Integer, ByVal Speed As Double)
Delegate Sub InicializarProgressBar(ByVal Valor As Long)
Delegate Sub AtualizarProgressBar(ByVal Valor As Long)
Delegate Sub AtualizacaoCompleta()
Delegate Sub IniciarDownload()
Private Sub TarefaCompleta()
Pgb.Visible = False
PicCerto2.Location = New Point(Label5.Left - PicCerto2.Width, Label5.Top + (Label5.Height - PicCerto2.Height) / 2)
PicCerto2.Visible = True
PicSeta3.Visible = False
Label8.Visible = False
BtnAtualiza.Enabled = True
BtnFechar.Enabled = True
End Sub
Private Sub InicializaProgressBar(ByVal Valor As Long)
Pgb.Maximum = Valor
Label5.Visible = True
Pgb.Location = New Point(Label5.Left, Label5.Bottom)
Pgb.Visible = True
PicSeta3.Location = New Point(Label5.Left - PicSeta3.Width, Label5.Top + Label5.Height / 2 - PicSeta3.Height / 2)
PicSeta3.Visible = True
Label8.Visible = True
End Sub
Private Sub AtualizaProgressBar(Valor As Long)
Pgb.Value = Valor
Label8.Text = FormatPercent(Valor / Pgb.Maximum, 0)
End Sub
Private Sub DownloadComplete(ByVal Cancelar As Boolean)
PicSeta2.Visible = False
Label9.Visible = False
PicCerto3.Location = New Point(Label4.Left - PicCerto3.Width, Label4.Top + (Label4.Height - PicCerto3.Height) / 2)
PicCerto3.Visible = True
Pgb.Value = 0
Pgb.Visible = False
End Sub
Private Sub IniciaDownload()
Label4.Visible = True
Label9.Visible = True
PicSeta2.Location = New Point(Label4.Left - PicSeta2.Width, Label4.Top + (Label4.Height - PicSeta2.Height) / 2)
PicSeta2.Visible = True
Pgb.Value = 0
Pgb.Location = New Point(Label4.Left, Label4.Bottom)
Pgb.Visible = True
End Sub
Private Sub AlterarTextos(ByVal Length As Long, ByVal Pos As Integer, ByVal percent As Integer, ByVal Tempo As Double)
Pgb.Maximum = Length
Pgb.Value = Pos
Label9.Text = Math.Round((Pos / 1024), 2) & [Ô] KB de [Ô] & Math.Round((Length / 1024), 2) & [Ô]KB ([Ô] & Pgb.Value & [Ô] %)[Ô]
If Tempo = 0 Then
Label9.Text = [Ô]Calculando...[Ô]
Else
Label9.Text = Math.Round((Tempo / 1024), 2) & [Ô] KB/s[Ô]
End If
[ô]Pgb.Value = percent
End Sub
Private Sub BakWork_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BakWork.DoWork
Dim NR As New System.Text.RegularExpressions.Regex([Ô]
[Ô])
Dim Arq As New System.IO.StreamReader(NomeArq)
Dim St As String = Arq.ReadToEnd()
Arq.Close()
Arq.Dispose()
Arq = New System.IO.StreamReader(NomeArq)
Dim Qtd As Long = NR.Matches(St).Count + 1
Dim AtualPGB As New InicializarProgressBar(AddressOf InicializaProgressBar)
Me.Invoke(AtualPGB, Qtd)
Try
Using ConDB As SqlConnection = New SqlConnection(PDns)
ConDB.Open()
Dim Posi As Long = 0
Dim Txt As String = [Ô][Ô]
Dim L As Integer = 0
Using RstCmd As SqlCommand = New SqlCommand([Ô]Select Col_Length([ô]NCMS[ô], [ô]Nome[ô])[Ô], ConDB)
L = RstCmd.ExecuteScalar
End Using
Do
Posi += 1
Txt = Arq.ReadLine
If Posi > 1 AndAlso Not Txt Is Nothing Then
Dim A() As String = Txt.Split([Ô];[Ô])
If Val(A(2)) = 0 Then
Dim Crit As String = [Ô]Update TabelaIBPT SET Tabela = 0,IbpEx = [ô][Ô] & A(1) & [Ô][ô],AliqNac = [Ô] & A(4) & [Ô], AliqImp = [Ô] & A(5) & [Ô], AliqEst = [Ô] & A(6) & [Ô],AliqMun = [Ô]
Crit += A(7) & [Ô], DiaIni = [ô][Ô] & A(8) & [Ô][ô], DiaFim = [ô][Ô] & A(9) & [Ô][ô],Chave = [ô][Ô] & A(10) & [Ô][ô],Versao = [ô][Ô] & A(11) & [Ô][ô],Fonte = [ô][Ô] & A(12) & [Ô][ô] where Ncms = [ô][Ô] & A(0)
Crit += [Ô][ô] IF @@ROWCOUNT = 0 [Ô]
Crit += [Ô]Insert Into TabelaIBPT(NCMS, Tabela, IbpEx, AliqNac, AliqImp, AliqEst, AliqMun, DiaIni, DiaFim, Chave,Versao, Fonte) VALUES([ô][Ô] & A(0).Trim & [Ô][ô], 0,[ô][Ô]
Crit += A(1).Trim & [Ô][ô],[Ô] & A(4) & [Ô],[Ô] & A(5) & [Ô],[Ô] & A(6) & [Ô],[Ô] & A(7) & [Ô],[ô][Ô] & A(8) & [Ô][ô],[ô][Ô] & A(9) & [Ô][ô],[ô][Ô] & A(10) & [Ô][ô],[ô][Ô] & A(11) & [Ô][ô],[ô][Ô] & A(12) & [Ô][ô])[Ô]
Using RstCmd As SqlCommand = New SqlCommand(Crit, ConDB)
RstCmd.ExecuteNonQuery()
End Using
A(3) = Strings.Left(A(3), L)
Crit = [Ô]Update NCMS Set Nome = [ô][Ô] & A(3) & [Ô][ô] where Ncms = [ô][Ô] & A(0).Trim & [Ô][ô] [Ô]
Crit += [Ô]IF @@ROWCOUNT = 0 [Ô]
Crit += [Ô]Insert Into NCMS(NCMS, Nome) Values([ô][Ô] & A(0).Trim & [Ô][ô],[ô][Ô] & A(3).Trim & [Ô][ô])[Ô]
Using RstCmd As SqlCommand = New SqlCommand(Crit, ConDB)
RstCmd.ExecuteNonQuery()
End Using
End If
End If
Dim PosiPgb As New AtualizarProgressBar(AddressOf AtualizaProgressBar)
Me.Invoke(PosiPgb, Posi)
Loop Until Txt Is Nothing
End Using
Arq.Close()
Arq.Dispose()
Dim Compl As New AtualizacaoCompleta(AddressOf TarefaCompleta)
Me.Invoke(Compl)
Catch ex As Exception
Arq.Close()
Arq.Dispose()
MessageBox.Show(ex.Message, [Ô]Atualização IBPT[Ô], MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
A figura anexa mostra a tela que é alimentada pela rotina
O que eu queria fazer, é o seguinte;
Declarei minha classe;
no meu botão de carregar (ou até mesmo no load do formulário)
E o metodo da classe;
Tentei utilizar +- o exemplo do PLUGSOFTSM mas apareceu esse erro:
Em Form1.Invoke(atgrid, result) : Não é possÃvel chamar Invoke ou BeginInvoke em um controle antes da criação do identificador de janela.
Declarei minha classe;
Private WithEvents DD As MCliente = New MCliente
no meu botão de carregar (ou até mesmo no load do formulário)
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click [ô]Normal
ThreadPool.QueueUserWorkItem(AddressOf DD.TodosNoFunction)
End Sub
Delegate Sub AtualizarGrid(Valor As List(Of Clientes))
Public Sub AtualizarGrids(Valor As List(Of Clientes))
Me.DataGridView2.DataSource = Valor
End Sub
E o metodo da classe;
Public Class MCliente
Public Event alllist(a As List(Of Clientes))
Public Sub TodosNoFunction()
Dim SqlAll As String = [Ô]SELECT * FROM clientes;[Ô]
Dim result As New List(Of Clientes)
Try
Using conn As New MySqlConnection([Ô]server = localhost;user Id = root;password = 123456;database = test[Ô])
Using cmd As New MySqlCommand(SqlAll, conn)
conn.Open()
Using rdr As MySqlDataReader = cmd.ExecuteReader()
While rdr.Read()
result.Add(New Clientes(rdr.Item([Ô]idclientes[Ô]), rdr.Item([Ô]nome[Ô]), rdr.Item([Ô]idade[Ô])))
End While
End Using
End Using
End Using
Catch ex As Exception
End Try
Dim atgrid As New Form1.AtualizarGrid(AddressOf Form1.AtualizarGrids)
Form1.Invoke(atgrid, result)
End Sub
Tentei utilizar +- o exemplo do PLUGSOFTSM mas apareceu esse erro:
Em Form1.Invoke(atgrid, result) : Não é possÃvel chamar Invoke ou BeginInvoke em um controle antes da criação do identificador de janela.
up...
bem, desde o começo foi dito e sugerido, threads, background, task não são besteirinhas pra qq iniciante, ainda mais se for pensar num copiar e colar sem entender pra poder contornar os erros......
fiz um ctrl+c ctrl+v do código do PLUGSOFTSM, colei todo num form, inclui alguns controles, exclui algumas rotinas, troquei todo miolo de trabalho q tinha no dele, pq além de não trabalhar com esses dados, eu nem tenho entendimento dos mesmos, coloquei uma rotina das mais básicas e simples de qq inicio de trabalho com banco de dados, pra abrir um banco de dados, ler todos os registros, e um a um incluir em outra base, e funcionou, ainda modifiquei as rotinas pra mostrar X / tantos registros, mostrar a % e preencher a barra de progresso.....
não tem o q reclamar, o código mastigado esta perfeito, cabe adaptar ao uso, mas pra isso é necessário entendimento pelo menos do q copia pra contornar os erros como disse antes......se prestar atenção a todos delegates já daria pra começar a entender como o mecanismo funciona......
quer algo simples....
esse frmcarregando, crie um form sem nada, so um label carregando.... e um progress bar atrelado a um timer pra dar movimento ao progress....
qnd termina a rotina...
de boa cara, com isso sera muito mais feliz, algo básico simples q não deixa tudo parado qnd trabalha......
fiz um ctrl+c ctrl+v do código do PLUGSOFTSM, colei todo num form, inclui alguns controles, exclui algumas rotinas, troquei todo miolo de trabalho q tinha no dele, pq além de não trabalhar com esses dados, eu nem tenho entendimento dos mesmos, coloquei uma rotina das mais básicas e simples de qq inicio de trabalho com banco de dados, pra abrir um banco de dados, ler todos os registros, e um a um incluir em outra base, e funcionou, ainda modifiquei as rotinas pra mostrar X / tantos registros, mostrar a % e preencher a barra de progresso.....
não tem o q reclamar, o código mastigado esta perfeito, cabe adaptar ao uso, mas pra isso é necessário entendimento pelo menos do q copia pra contornar os erros como disse antes......se prestar atenção a todos delegates já daria pra começar a entender como o mecanismo funciona......
quer algo simples....
[ô]thread da telinha carregando na tela qnd for pra alguma rotina demorada
Trd = New Thread(AddressOf Aguarda)
operacao = [Ô]Restauração[Ô]
Trd.Start()
Public Sub Aguarda()
[ô]thread de processo, mostra a tela processando
Dim f As New frmCarregando()
f.TopMost = True
f.ShowDialog()
End Sub
esse frmcarregando, crie um form sem nada, so um label carregando.... e um progress bar atrelado a um timer pra dar movimento ao progress....
qnd termina a rotina...
[ô]finalizando thread da telinha e sumindo com a mesma
frmCarregando.Hide()
frmCarregando.Dispose()
Trd.Abort()
de boa cara, com isso sera muito mais feliz, algo básico simples q não deixa tudo parado qnd trabalha......
Entendo que falar sobre threads é extremamente complicado, porem tenho que dar um jeito de implementar no projeto (digamos que o cliente reclama por causa de 1 segundo travado) o que eu queria é;
Através do form, chamar um metodo/evento em minha classe que irá carregar dados, e no meio desse carregamento ele dispare eventos (atualizando o status) e no final, dispara um evento do tipo List(of) para eu criar os padrões em um FlowLayout
Através do form, chamar um metodo/evento em minha classe que irá carregar dados, e no meio desse carregamento ele dispare eventos (atualizando o status) e no final, dispara um evento do tipo List(of) para eu criar os padrões em um FlowLayout
entenda o principal, vc tem q prometer o q sabe, não pode prometer o q não sabe, se quer prometer o q não sabe tem q ter tempo de estudar e aprender....(pediram uma vez pra eu migrar algo pre histórico q gerava boletos, primeiro fui ver se teria como pegar os dados do programa atual, blz, depois de entender o armazenamento fui aprender a desenvolver o boleto, pq a gerente havia vendido uma carteira q não conseguia com o boleto.dll, fui na unha e aprendi a fazer o boleto, como fui brigar c a gerente do cliente q vendeu uma carteira q não permitia o boleto dele, depois de brigar c ela fui alertar o cliente sobre a venda da carteira q interessava a gerente e não atendia o cliente....so depois desse empasse q pude dar continuidade, não dei prazo nem nada, tudo eu teria q aprender a fazer, e um programa cheio de telas q atendesse ainda a usuários de 20 anos do velho programa em tela preta, mesmo com botões tudo tinha q funcionar com atalhos de F-alguma coisa, igual as velhas telas....)
tem ai no tópico N formas de fazer, bem ao estilo copia e cola pronto, basta copiar e colar, e ai entra a parte difÃcil (muito difÃcil mesmo), adaptar ao seu código, precisa entender o q o código faz pra adaptar corretamente.....até código de deixar a mensagem de aguarde na tela enquanto carrega algo já mostrei como fazer, e com thread tmb, já q o problema é usar thread
tem ai no tópico N formas de fazer, bem ao estilo copia e cola pronto, basta copiar e colar, e ai entra a parte difÃcil (muito difÃcil mesmo), adaptar ao seu código, precisa entender o q o código faz pra adaptar corretamente.....até código de deixar a mensagem de aguarde na tela enquanto carrega algo já mostrei como fazer, e com thread tmb, já q o problema é usar thread
Faça seu login para responder