Why am I getting this error:"Cross-thread operation not valid: Control lbFolders accessed from a thread other than the thread it was created on."?

This is baffling me, maybe somebody can shine the light of education on my ignorance. This is in a C# windows app. I am accessing the contents of a listbox from a thread. When I try to access it like this

prgAll.Maximum = lbFolders.SelectedItems.Count;
I get the error. However, here is the part I don't get. If I comment out that line, the very next line
foreach (string dir in lbFolders.SelectedItems)
executes just fine.

Edit: As usual, my communication skills are lacking. Let me clarify.

I know that accessing GUI items from threads other than the ones they were created on causes problems. I know the right way to access them is via delegate.

My question was mainly this: Why can I access and iterate through the SelectedItems object just fine, but when I try to get (not set) the Count property of it, it blows up.


You can't access GUI elements from a separate thread. Use a delegate to make the change.

eg.

lblStatus.Invoke((Action)(() => lblStatus.Text = counter.ToString()));

or older skool:

lblTest.Invoke((MethodInvoker)(delegate() 
{ 
  lblTest.Text = i.ToString(); 
}));

I've got a blog post on how to do this in all the .Net releases here.


prgAll.Maximum = lbFolders.SelectedItems.Count;

On that line you perform an assignment (set/add), which by default is not thread-safe.

On the second line it's just a get operation, where thread-safety merely doesn't matter.

EDIT: I don't mean access to the prgAll element.

Accessing the Count property changes the internal state of the ListBox inner collection, that is why it throws the exception.


The Count property of SelectedItems is not thread-safe, so you can't use it cross-thread.