让我再试一次...
1.) 将ListView拖到窗体上
2.) 将BackgroundWorker拖到窗体上
3.) 创建一个方法来遍历ListViewItem集合
private void LoopThroughListItems()
{
foreach (ListViewItem i in listView1.CheckedItems)
DoSomething();
}
4.) 在BackgroundWorker的DoWork事件中添加代码调用LoopThroughListItems()
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
LoopThroughListItems();
}
5.) 在表单加载时 - 在主线程上执行代码(它可以正常工作),然后在backgroundWorker线程上执行代码(它会失败)。
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.) 修改您的代码,使用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.) 再次运行应用程序 - 现在它可以在UI线程和非UI线程上工作。
这解决了问题。检查IsInvokeRequired/Invoking是一种常见的模式,您将经常使用它(这就是为什么它包含在所有控件中的原因)。如果您在各个地方都这样做,您可以聪明地将其全部包装起来 - 如此描述:自动化InvokeRequired代码模式
BackgroundWorker
,那么您表单中的每个控件都已经可读了... - Marco