Let me take another stab at this...
1.) Drag a ListView onto the Form
2.) Drag a BackgroundWorker onto the Form
3.) Create a method do iterate through the ListViewItem collection
private void LoopThroughListItems()
{
foreach (ListViewItem i in listView1.CheckedItems)
DoSomething();
}
4.) Add code to call LoopThroughListItems() inside the BackgroundWorker's DoWork Event
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
LoopThroughListItems();
}
5.) In your Form Load - execute the code on the main thread (it works) then on the backgroundWorkder thread (it fails)
private void Form1_Load(object sender, EventArgs e)
{
// Try it on the UI Thread - It works
LoopThroughListItems();
// Try it on a Background Thread - It fails
backgroundWorker1.RunWorkerAsync();
}
6.) Modify your code to use IsInvokeRequired/Invoke
private void LoopThroughListItems()
{
// InvokeRequired == True when executed by non-UI thread
if (listView1.InvokeRequired)
{
// This will re-call LoopThroughListItems - on the UI Thread
listView1.Invoke(new Action(LoopThroughListItems));
return;
}
foreach (ListViewItem i in listView1.CheckedItems)
DoSomething();
}
7.) Run the app again - now it works on the UI thread and the non-UI thread.
That solve the problem. The checking IsInvokeRequired/Invoking is a common pattern you'll get used to a lot (which is why it's included on all Controls). If you are doing it all over the place, you can do something clever and wrap it all up - as described here: Automating the InvokeRequired code pattern