我遇到一个问题,我的部分代码没有运行,除非我在某个时刻在调试模式下放置一个断点,或者我放了一个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之前没有遇到任何断点,它将永远不会调用该方法。
我认为它与线程没有同步有关,但我对线程如何正确诊断问题知之甚少。
答案 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
。