Call with C # text box

My program uses an event handler to receive data from my serial port. The idea is to get the data that the resulting text is then added to the text field (rx). I did not have this problem, but something has changed, and I cannot understand that. So now I am revising the processing method.

While loading my winform form, the last thing I do is

if (!serialPort1.IsOpen) { serialPort1.Open(); serialPort1.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler); } 

Then I have an event handler

 private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { string indata1 = serialPort1.ReadExisting(); // rx.Text = " "; accidentally posted this. it was from trial and error. rx.AppendText(Environment.NewLine + indata1); } 

When I run the program, it stops at rx.AppendText(Environment.NewLine + indata1); and gives an error

invalidoperationexception was unhandled: "Control" accessed from except the thread on which it was created.

From what I was able to read, I suggest using invoke or BeginInvoke .

I have never had a problem adding text, so now I canโ€™t understand why this is a problem. Also, from what I read when I called, I just do not understand.

Can someone help me figure out how to use an invoke instance for my situation? or maybe show me another way to add a text box?

+4
source share
2 answers

Typically, the exception you see occurs when you run in debug mode, and if you run the application in release mode, you are unlikely to see this exception.

However, it is best to use invoke as you read. Something like that:

  private delegate void RefreshTextBox(); private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) { //this event is raised in an event separate from UI thread, //so InvokeRequired must be checked and Invoke called to update UI controls. if (this.InvokeRequired) { RefreshTextBox d = new RefreshTextBox(RefreshTextBoxResults); Invoke(d); } else { RefreshTextBoxResults(); } } private void RefreshTextBoxResults() { string indata1 = serialPort1.ReadExisting(); rx.Text = " "; rx.AppendText(Environment.NewLine + indata1); } 

The first time you see this challenge, it is almost impossible to follow, but look carefully and give it some time, and it will make sense. Promise. :)

+4
source

Updates in GUI applications should only be performed on the GUI thread. Another thread attempting to directly update the GUI components will result in either the described error or seemingly random behavior.

The role of Invoke and friends is to include an additional thread to safely redirect GUI updates to the GUI thread, which will then process them from the queue.

In your case (assuming WinForms here):

 rx.BeginInvoke( (Action)(() => { rx.AppendText(Environment.NewLine + indata1); })); 

BeginInvoke is asynchronous, so the thread calling it will not wait for the actual updates to be processed before continuing, while Invoke is synchronous.

+5
source

All Articles