none
System.InvalidOperationException alterando o texto de um botao RRS feed

  • Pergunta

  • Boa Tarde,

    Estou desenvolvendo uma aplicação em C# para controle de um sistema de aquisições de um microcontrolador (MSP430) via serial. A comunicação é estabelecida normalmente mas durante uma das primeiras operações o Visual Studio apresenta a seguinte exceção:

    System.InvalidOperationException was unhandled
    Message=Operação entre threads inválida: controle 'EnableChargeButton' acessado de um thread que não é aquele no qual foi criado.

    Não estou utilizando threads no código, na verdade, utilizo o evento DataReceived do Serial para fazer o controle de ações a serem tomadas a partir do envio de informações do microcontrolador. Segue abaixo o trecho de código responsável pelo erro:

    private void SerialMSP_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                StreamWriter logfile = new StreamWriter("acquisition.dat", true);   // Criação do arquivo de log para aquisições
    
                try
                {
                    bufferadc = SerialMSP.ReadTo("p");
                }
                catch
                {
                    MessageBox.Show("Tempo limite atigindo!", "Error", MessageBoxButtons.OK);
                }
    
                switch (bufferadc)
                {
                    case "EC":                                                      // ADC ligado
                        label_status1.Text = "Conectado";
                        EnableChargeButton.Text = "Ligar carga"; // <-- Linha da exceção
                        EnableChargeButton.Enabled = true;
                        AcqButton.Enabled = true;
                        break;
    
                    case "CL":                                                      // Carga ligada
                        EnableChargeButton.Text = "Desligar carga";
                        carga = true;
                        break;
    
                    case "CD":                                                      // Carga desligada
                        EnableChargeButton.Text = "Ligar carga";
                        carga = false;
                        break;
    
                    case "AS":                                                      // Aquisições enviadas
                        converter();
                        plot();
                        break;
    
                    default:                                                        // Dado de aquisição V-I
                        try
                        {
                            logfile.WriteLine(bufferadc);
                        }
                        catch
                        {
                            MessageBox.Show("Não foi possível acessar o arquivo de log", "Error", MessageBoxButtons.OK);
                        }
    
                        break;
                }
    
                bufferadc = null;
                
                try
                {
                    logfile.Dispose();
                    logfile.Close();
                }
                catch
                {
                    MessageBox.Show("Não foi possível fechar o arquivo de log", "Error", MessageBoxButtons.OK);
                }
    
                Cursor.Current = Cursors.Default;
            }
    O que posso fazer?


    • Editado Lucas Arcanjo quarta-feira, 19 de outubro de 2016 19:41
    quarta-feira, 19 de outubro de 2016 19:40

Respostas

  • Bom dia, 

    Apesar de você não ter implementado manualmente o uso de threads, o evento DataReceived pode estar sendo disparado através de outra thread.

    Veja esta resposta do StackOverflow: http://stackoverflow.com/a/10775421/1184708

    No seu caso você teria que fazer algo assim:

    private void SerialMSP_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
            {
                StreamWriter logfile = new StreamWriter("acquisition.dat", true);   // Criação do arquivo de log para aquisições
    
                try
                {
                    bufferadc = SerialMSP.ReadTo("p");
                }
                catch
                {
                    MessageBox.Show("Tempo limite atigindo!", "Error", MessageBoxButtons.OK);
                }
    
                switch (bufferadc)
                {
                    case "EC":                                                      // ADC ligado
                        label_status1.Text = "Conectado";
                        SetButtonProp("Ligar carga", true);
                        AcqButton.Enabled = true;
                        break;
    
                    case "CL":                                                      // Carga ligada
                       SetButtonProp("Desligar carga");
                        carga = true;
                        break;
    
                    case "CD":                                                      // Carga desligada
                        SetButtonProp("Ligar carga");
                        carga = false;
                        break;
    
                    case "AS":                                                      // Aquisições enviadas
                        converter();
                        plot();
                        break;
    
                    default:                                                        // Dado de aquisição V-I
                        try
                        {
                            logfile.WriteLine(bufferadc);
                        }
                        catch
                        {
                            MessageBox.Show("Não foi possível acessar o arquivo de log", "Error", MessageBoxButtons.OK);
                        }
    
                        break;
                }
    
                bufferadc = null;
                
                try
                {
                    logfile.Dispose();
                    logfile.Close();
                }
                catch
                {
                    MessageBox.Show("Não foi possível fechar o arquivo de log", "Error", MessageBoxButtons.OK);
                }
    
                Cursor.Current = Cursors.Default;
            }
    
    delegate void SetButtonPropCallback(string text, bool? enabled);
    
    private void SetButtonProp(string text, bool? enabled)
    {
      if (this.EnableChargeButton.InvokeRequired)
      { 
        SetButtonPropCallback d = new SetButtonPropCallback(SetButtonProp);
        this.Invoke(d, new object[] { text, enabled });
      }
      else
      {
        this.EnableChargeButton.Text = text;
    
        if (enabled.HasValue)
            this.EnableChargeButton.Enabled = enabled;
      }
    }


    If you found this post helpful, please "Vote as Helpful". If it actually answered your question, remember to "Mark as Answer".

    Se achou este post útil, por favor clique em "Votar como útil". Se por acaso respondeu sua dúvida, lembre de "Marcar como Resposta".

    quinta-feira, 20 de outubro de 2016 09:48