views:

60

answers:

2

Hey,

I am working on some code where I initialize an object (in this case a form), which then idles until it either receives a message from someone, or one of its methods is invoked directly.

In my form, I have a listbox (lTester) that shows all calls made to this form. During run-time I get the following error:

Cross-thread operation not valid: Control 'lTester' accessed from a thread other than the thread it was created on.

I have not started any threads manually, in fact I have never worked with them and don't really know how C# manages the UI components internally. Is there any way to get around this?

Thanks,

PM

+2  A: 

Before you touch the ITester you have to check the value of InvokeRequired. If it is true, call the function Invoke

Oskar Kjellin
+1  A: 

If you want to know where your thread is comming from, you can place a break point in the method you know are being called (where the error is generated), open the Threads and Stack Trace windows in VS and see what initiated the call to begin with.

Even though the code is located in your Form class, the caller still desides which thread the call is executed in. That's why, as Oskar stated, you have to check if you need to Invoke to the main thread. There are tons of examples on how to do this, just Google InvokeRequired and go from there.

Let me know if you need an example.

Paw Baltzersen
OK, I guess that'll do it for this case. What bothers me is that I don't understand where these multiple threads are coming from, i.e.: how all of this works out internally.
And since you're not posting any code, neither do we. You say "receive messages from someone", what does that mean exactly? Receive how? From who or what?
Lasse V. Karlsen
That was a mistake my tester class actually has events that it can raise and that are caught and handled by other classes. as far as receiving messages I update my listbox via the lTester.Items.Add(""); command. In other words I have a method called update and in it I run the above command. So from another class I would call tester.update(x)
Mystery solved. Tester exposes events that others are subscribed to. When Tester raises an event, new threads are created for the listeners to receive. Think about it - if no new threads were created, the event source would have to iterate each listener one-by-one calling their delegate and waiting for that to complete before moving onto the next. Now you have another object that is running on a different thread than Tester. So when you call back to tester, your call is not on the main thread that Tester was created on. So if Tester's delegate tries to access UI controls it will get an error.
Erik Noren