让我再试一次……
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.)在您的表单加载中 - 在主线程上执行代码(它可以工作)然后在 backgroundWorkder 线程上(它失败)
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 代码模式