0

I have this simple code that I'm trying to parallelize:

 Parallel.For (0,countimages, i => { picbox[i] = new PictureBox(); picbox[i].Image = image; TableLayoutPanel1.Controls.Add(picbox[i], column, row); column+=1; }); 

and I get this error:

ParallelFor | Cross-thread operation not valid: Control TableLayoutPanel1 accessed from a thread other than the thread it was created on.

What am I doing wrong?

3
  • What language is it? C#? Commented Oct 16, 2013 at 23:21
  • You created the TableLayoutPanel on the main thread (guessing) and accessing it on another. Create a delegate to handle the adding of the control to the TableLayoutPanel1 Commented Oct 16, 2013 at 23:22
  • @ Sorceri can you post an example? Commented Oct 17, 2013 at 13:40

1 Answer 1

0

UI changes can only be made from the thread the UI elements were created on. Your code is running in multiple threads and each of them is trying to change the TableLayoutPanel1.Controls collection.

You have to marshal your calls back to the UI thread.

You're also probably going to have unexpected behavior related to the column value since it looks like you're trying to share it between threads. It's possible a few controls will try to add to the same column before that value is incremented.

Sign up to request clarification or add additional context in comments.

3 Comments

Hmm so what's the best option for this? not use the parallel stuff?
Essentially, yes. Parallel (in this way) is best used when you want to perform iteration-isolated work. Meaning the task you're accomplishing for any one item in the collection does not depend on other iterations. You're violating that with the column variable. In addition you're touching UI which adds that little complication. Parallel is great for dispatching messages to queues or in-place converting data structures from one type to another. Laying out UI isn't so good.
You could use a parallel process to populate a memory collection of the images already read from disk and then on the UI thread you could use a single loop to lay them all out. You could use a producer-consumer queue where multiple threads are feeding the queue (to load resources and make them available) and the UI threads pulls and adds the UI elements. Is your current design too slow or glitchy on the UI? Maybe you're loading too many resources at once - use a background worker to load and notify you when done and handle UI update then. Lots of options.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.