views:

630

answers:

3

I have an application in which I am running a separate thread.

Dim thread As New System.Threading.Thread(AddressOf Main)
thread.Start()

However, the thread makes reference to an textbox named Output, and it generates this error upon execution:

System.InvalidOperationException was unhandled
  Message="Cross-thread operation not valid: Control 'Output' accessed from a thread other than the thread it was created on."
  Source="System.Windows.Forms"

(message shortened for space)

How can I make the operations run on another thread, but still use the Output object? I cannot call a subroutine to do that for me, as it generates the exact same error.

The method called is AppendText, by the way.

I am probably missing something important here, so thanks for the help!

+1  A: 

You should use Control.Invoke or Control.BeginInvoke to call your subroutine.

danbystrom
Inside of the sub?
Cyclone
Can you give a code example?
Cyclone
@Cyclone: see this other post for examples of using InvokeRequired and Invoke: http://stackoverflow.com/questions/571706/shortest-way-to-write-a-thread-safe-access-method-to-a-windows-forms-control.
David Andres
+2  A: 

Instead of just calling the AppendText method you need to force it to execute on the correct thread. So, if you have a call like this:

myTextBox.AppendText("some text")

...you need to change it to this:

myTextBox.BeginInvoke(New Action(Of String)(AddressOf myTextBox.AppendText), "some text")

You can use either Invoke or BeginInvoke. In this case, since AppendText doesn't have any return value, BeginInvoke is a good choice (the difference is that Invoke will block the current thread while the GUI thread executes the AppendText method, while BeginInvoke will make the call asynchronously instead).

Fredrik Mörk
That did it!
Cyclone
+1  A: 

This exception is a very popular exception when using a thread.Some operation are not thread safe (like accessing a control on a thread other than its own thread) so framework is preventing these kind of problems. To solve it you can either use Control.Invoke method to call a delegate that is in the same thread the control or you can use a background worker.

Here you can find a sample of first approach

and

Here you can find a sample of a background worker

Beatles1692