Je surveillerais les données reçues sur un port série avec mon ordinateur et un Arduino. Sur l'arduino, le sketch envoie à l'USB la chaîne "aabb" evry 300ms. Avec pc je veux écouter, et en temps réel imprimer la chaîne dans un contrôle (Textbox
). Pour ce faire, je crée un nouveau thread qui écoute dans une boucle ce qui arrive dans le port série, et quand cela arrive, il écrit par Invoke la chaîne dans la zone de texte. Les procédures fonctionnent si je déploie dans la classe du formulaire mais si j'utilise une classe externe, ce n'est pas le cas. Pour mieux expliquer la question, je coller le code de la classepourquoi Invoke ne fonctionne pas dans une autre classe
class SerialPortManager
{
public SerialPort Serial = new SerialPort();
private Thread thr;
private string Log;
public TextBox textLog;
public string LastString;
public bool thrIsAlive;
[Browsable(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[EditorBrowsable(EditorBrowsableState.Advanced)]
[IODescriptionAttribute("ControlInvokeRequiredDescr")]
public bool InvokeRequired { get; private set; }
//DISPOSE
public void Dispose()
{
this.Dispose();
}
//SET Textobox LOG
public void SetLogTxtB (TextBox txt)
{
textLog = txt;
}
//PORTE DISPONIBILI
public string[] Available_Ports()
{
return SerialPort.GetPortNames();
}
//COSTRUTTORI
public SerialPortManager(string portname, int baudrate,bool InitializeConn)
{
Serial.BaudRate = baudrate;
Serial.PortName = portname;
if (InitializeConn == true) Serial.Open();
}
public SerialPortManager()
{
}
//SETTA I PARAMETRI E INIZIALIZZA LA CONNESSIONE
public void SetConnectionParam(string portname, int baudrate, bool initializeConn)
{
Serial.Close();
Serial.Dispose();
Serial = new SerialPort();
Serial.BaudRate = baudrate;
Serial.PortName = portname;
if (initializeConn == true) Serial.Open();
}
//ASYNC LISTENER
public void AsyncListener()
{
thrIsAlive = true;
thr = new Thread(ThreadReader);
thr.Start();
}
//PROCEDURA PER APPEND
public void AppendTextBox(string value)
{
if (InvokeRequired)
{
this.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
textLog.Text += value;
}
private void Invoke(Action<string> action, params object[] v)
{
throw new NotImplementedException();
}
void ThreadReader()
{
while (thrIsAlive)
{
string temp = Serial.ReadLine();
LastString = temp;
Log += LastString + "\n";
AppendTextBox(LastString + "\n");
}
}
}
Dans la forme que j'écris trois lignes
SerialPortManager PortMan = new Driver_Arduin.SerialPortManager("COM3", 9600,true);
PortMan.SetLogTxtB(textBox1);
PortMan.AsyncListener();
Si je tente d'exécuter le programme, il renvoie l'erreur "opération cross-thread ne permis". Maintenant, alors que je poste cette demande, je décide de faire une dernière tentative et changer la méthode AppendTextBox à:
public void AppendTextBox(string value)
{
if (textLog.InvokeRequired)
{
try
{
textLog.Invoke(new Action<string>(AppendTextBox), new object[] { value });
return;
}
catch (ObjectDisposedException)
{
thrIsAlive = false;
}
}
textLog.Text += value;
}
Et cela fonctionne enfin. Maintenant vérifié la puissance de Stackoverflow qui a résolu le problème avant de poster, je saurais pourquoi mon code fonctionne. Merci