Soul3lade
Soul3lade

Reputation: 568

Code not executing without breakpoint

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

Answers (1)

Scott Chamberlain
Scott Chamberlain

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

Related Questions