Inquiridor
Backgroudwork C#

Pergunta
-
Ola estou com erro que não sei como fazer, tenho um LABEL q é atualizado por uma função porem sa erro : Operação entre threads invalida : controle 'lbMSG' acessado de um thread que nao é aquele no qual foi criado.
Se alguém puder me ajudar.
private void ConectaDBF(string TextoComando) { //lbMSG.Invoke(new MethodInvoker(() => { lbMSG.Text = "Comando iniciado... " + DateTime.Now.ToString(); })); lbMSG.Text = "Comando iniciado... " + DateTime.Now.ToString(); lbMSG.ForeColor = Color.White; lbMSG.Refresh(); //CaminhoArquivo = BuscaArquivo.FileName; try { DateTime TempoInicio = DateTime.Now; OleDbConnection oConn = new OleDbConnection(); oConn.ConnectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + CaminhoSource + ";Extended Properties=dBASE IV;"; oConn.Open(); OleDbCommand oCmd = oConn.CreateCommand(); oCmd.CommandText = TextoComando; //DataTable dt = new DataTable(); dtComDBF = new DataTable(); dtComDBF.Load(oCmd.ExecuteReader()); oConn.Close(); /*------------------------------------------------------------*/ //if (dt.Columns.Count > 0) //{ // MessageBox.Show(dt.Columns.Count.ToString()); // foreach (DataRow linha in dt.Rows) // { // GravaTxt("Datatable.txt", linha["B1_CODPRO"].ToString() + " | "); // } // MessageBox.Show("Concluido !"); //} /*------------------------------------------------------------*/ double LinhasDt = Convert.ToDouble(dtComDBF.Rows.Count); ProgressBar.Maximum = Convert.ToInt32(LinhasDt); dgvDados.DataSource = dtComDBF; for (int i = 0; i < dtComDBF.Rows.Count; i++) { lbPercent.Text = Math.Round(((i / LinhasDt) * 100)).ToString("F2") + "%"; ProgressBar.Value = i; ProgressBar.Refresh(); lbPercent.Refresh(); } lbPercent.Text = "100%"; ProgressBar.Value = ProgressBar.Maximum; Tempo = Convert.ToString(DateTime.Now - TempoInicio); lbMSG.ForeColor = Color.White; registros = dgvDados.RowCount.ToString(); lbMSG.Text = "Tempo decorrido: " + Tempo + "\n" + registros + " : linhas afetadas"; } catch (Exception Erro) { lbMSG.ForeColor = Color.Orange; lbMSG.Text = "Comando inválido ! " + DateTime.Now.ToString(); MessageBox.Show("Erro! " + Erro.ToString()); } }
Todas as Respostas
-
Bom dia Cristiano!
Este problema ocorre pois está tentando modificar um controle (label lbMSG) fora da Thread que criou este controle. Por questões de segurança, uma Thread não deveria modificar o estado de outra Thread.
Para que você consiga atualizar este valor de fora da Thread "mãe" você terá que seguir algumas regrinhas para o compilador considerar que é uma operação "segura". Neste caso você poderá usar Delegates com Invokes ou BackgroundWorkers.
Vou te passar um exemplo com Invokes/Delegates.
Adicione este método à tua classe:
// Delegate para acesso da Thread ao Control do Form // Exemplo de uso: SetControlPropertyValue(tela, "text", "conexão recebida!"); delegate void SetControlValueCallback(Control oControl, string propName, object propValue); private void SetControlPropertyValue(Control oControl, string propName, object propValue) { if (oControl.InvokeRequired) { SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue); oControl.Invoke(d, new object[] { oControl, propName, propValue }); } else { Type t = oControl.GetType(); PropertyInfo[] props = t.GetProperties(); foreach (PropertyInfo p in props) { if (p.Name.ToUpper() == propName.ToUpper()) { p.SetValue(oControl, propValue, null); } } } }
E ao invés de chamar ibMSG.Text = "Tempo decorrido...etc";
Você vai chamar o método: SetControlPropertyValue(lbMSG, "text", "Tempo decorrido...etc");
Lembrando que o primeiro parâmetro é o Objeto que deseja atualizar, o segundo é o nome da propriedade que vai alterar e o terceiro é o novo valor (que pode ser string ou outro objeto). Tu podes adaptar para os diversos tipos de objetos e propriedades que precisar.
Segue link com mais detalhes sobre estas operações, sugiro a leitura para maiores esclarecimentos pois este problema é bastante comum:
https://docs.microsoft.com/pt-br/dotnet/framework/winforms/controls/how-to-make-thread-safe-calls-to-windows-forms-controls
Espero ter ajudado, um abraço!
- Sugerido como Resposta L 2014 quarta-feira, 22 de janeiro de 2020 13:58