没有断点的代码没有执行

时间:2015-03-04 23:29:38

标签: c# multithreading

我遇到一个问题,我的部分代码没有运行,除非我在某个时刻在调试模式下放置一个断点,或者我放了一个MessageBox。

每X秒调用一次的单独线程的方法。

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]);
        }

    }

从UI线程上的ListView中检索项目的方法

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;
        }

    }

在TimerHit中,如果删除了Messagebox,将永远不会调用GetXMLRecords。一旦MessageBox被添加,一切正常。如果我在for循环中放置一个断点,我也可以使一切工作正常。但是,如果在调用GetXMLRecords之前没有遇到任何断点,它将永远不会调用该方法。

我认为它与线程没有同步有关,但我对线程如何正确诊断问题知之甚少。

1 个答案:

答案 0 :(得分:2)

你的问题来自这个街区

    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;
    }

因为您调用了BeginInvoke,所以函数不会阻塞,并且会立即返回列表Items。尚未向该集合添加任何项目。当您显示消息框或在其中放置断点时,BeginInvoke中的代码有机会执行并填充集合,使Items.Count不为零并让for循环执行。

解决此问题的最快方法是使用屏蔽BeginInvoke调出Invoke