这是不安全的。当您从另一个线程读取控件时,UI 线程可以(并且可能会)更改控件的状态。您的读取可能会使控件处于半生不熟的状态。它现在可能看起来正在工作,但迟早会失败......可能无法预测和壮观。
不,您可能不需要使用 Invoke 模式。坦率地说……这种模式通常是最糟糕的选择。通常最好让您的工作线程完成繁重的工作,然后通过队列将新数据或进度信息发送到 UI 线程,并让 UI 线程通过计时器来获取这些信息。这有几个优点。
- 消除了昂贵的
Invoke
操作BeginInvoke
。
- UI 线程可以决定何时以及多久使用新数据更新自己,而不是让工作线程决定这一点。
- 您可以在工作线程上获得更多吞吐量,因为它不必等待
Invoke
返回。
- 不会像
BeginInvoke
.
- 它将 UI 和工作线程交互解耦。
您将需要枚举ListView
并构建一个单独的数据结构,然后工作线程可以安全地访问该数据结构。如果ListView
包含很多项目,请考虑与控件一起维护一个单独的集合。这样一来,您就可以在更长的时间内分散处理数据的损失,在这段时间内,它可能不会被太多人注意到。毕竟,我们不希望复制操作冻结 UI 线程,否则用户会注意到。AConcurrentBag
等可能是一个不错的选择,因为它可以在工作线程读取它时由 UI 线程安全地修改。