Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on [duplicate]
The data received in your serialPort1_DataReceived
method is coming from another thread context than the UI thread, and that's the reason you see this error.
To remedy this, you will have to use a dispatcher as descibed in the MSDN article:
How to: Make Thread-Safe Calls to Windows Forms Controls
So instead of setting the text property directly in the serialport1_DataReceived
method, use this pattern:
delegate void SetTextCallback(string text);private void SetText(string text){ // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (this.textBox1.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); this.Invoke(d, new object[] { text }); } else { this.textBox1.Text = text; }}
So in your case:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e){ txt += serialPort1.ReadExisting().ToString(); SetText(txt.ToString());}
I don't know if this is good enough but I made a static ThreadHelperClass class and implemented it as following .Now I can easily set text property of various controls without much coding .
public static class ThreadHelperClass{ delegate void SetTextCallback(Form f, Control ctrl, string text); /// <summary> /// Set text property of various controls /// </summary> /// <param name="form">The calling form</param> /// <param name="ctrl"></param> /// <param name="text"></param> public static void SetText(Form form, Control ctrl, string text) { // InvokeRequired required compares the thread ID of the // calling thread to the thread ID of the creating thread. // If these threads are different, it returns true. if (ctrl.InvokeRequired) { SetTextCallback d = new SetTextCallback(SetText); form.Invoke(d, new object[] { form, ctrl, text }); } else { ctrl.Text = text; } }}
Using the code:
private void btnTestThread_Click(object sender, EventArgs e) { Thread demoThread = new Thread(new ThreadStart(this.ThreadProcSafe)); demoThread.Start(); } // This method is executed on the worker thread and makes // a thread-safe call on the TextBox control. private void ThreadProcSafe() { ThreadHelperClass.SetText(this, textBox1, "This text was set safely."); ThreadHelperClass.SetText(this, textBox2, "another text was set safely."); }
you can simply do this.
TextBox.CheckForIllegalCrossThreadCalls = false;