Reputation: 568
I'm having an issue where part of my code is not running unless I either place a breakpoint in debugging mode at a certain point or I have a MessageBox put in.
Method on Seperate thread that is being called every X seconds.
public void TimerHit()
{
List<string> Items = form.getItems();
MessageBox.Show("Hello");
for (int i = 0; i < Items.Count; i = i + 2)
{
GetXMLRecords(Items[i], Items[i + 1]);
}
}
Method for Retrieving items from ListView on UI thread
public List<string> getItems()
{
List<string> Items = new List<string>();
if (listView1.InvokeRequired)
{
listView1.BeginInvoke(new MethodInvoker(() =>
{
for (int i = 0; i < listView1.Items.Count; i++)
{
Items.Add(listView1.Items[i].SubItems[0].Text.ToString());
Items.Add(listView1.Items[i].SubItems[1].Text.ToString());
}
}));
return Items;
}
else
{
for (int i = 0; i < listView1.Items.Count; i++)
{
Items.Add(listView1.Items[i].SubItems[0].Text.ToString());
Items.Add(listView1.Items[i].SubItems[1].Text.ToString());
}
return Items;
}
}
In TimerHit GetXMLRecords will never be called if the Messagebox is removed. Once the MessageBox is added everything works. I can also get everything to work if I place a breakpoint at the for loop. However, if it doesnt hit any breakpoints before calling GetXMLRecords, it will never call the method.
I'm assuming it has something to do with threads not syncing but I just dont know enough about how threads work to properly diagnose the issue.
Upvotes: 0
Views: 654
Reputation: 127603
Your problem comes from this block right here
if (listView1.InvokeRequired)
{
listView1.BeginInvoke(new MethodInvoker(() =>
{
for (int i = 0; i < listView1.Items.Count; i++)
{
Items.Add(listView1.Items[i].SubItems[0].Text.ToString());
Items.Add(listView1.Items[i].SubItems[1].Text.ToString());
}
}));
return Items;
}
Because you call BeginInvoke
the function does not block and the list Items
gets returned immediately. No items have yet been added to that collection. When you show a message box or put a breakpoint in it gives the code in the BeginInvoke
a chance to execute and populate the collection, making Items.Count
not zero and letting the for loop execute.
The fastest way to solve this is swap out the BeginInvoke
with the blocking Invoke
call.
Upvotes: 2