我正在尝试从BackgroundWorker
调用一个将用户控件添加到ListView
的方法:
private void AddItems(List<FileItem> fileItems) {
System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA);
Dispatcher.BeginInvoke(new Action(() => files.ItemsSource = fileItems));
}
用户控件files
在其构造函数中成功从fileItems
获取数据,但它会引发The calling thread must be STA, because many UI components require this.
异常。我已经尝试将[STAThread]
属性一一添加到所有父方法,但它仍然抛出异常。我应该在哪里添加此属性?
更新
另请注意,Dispatcher.BeginInvoke(new Action(() => files.Items.Clear()));
正在正确执行。
此Dispatcher
是指与 BGW 线程关联的线程,而不是 WPF/UI 线程。默认情况下,如果没有与当前线程关联,则将创建新的调度程序/上下文;在上下文中,这是完全没有用的。
如果从启动 BGW 的 UI 线程提供调度程序实例 (Dispatcher.CurrentInstance(,那么它"应该可以工作"。同样,正如 Hans 指出的那样,正确的 (WPF/UI( 调度程序对象应该可以通过与应用程序关联的调度程序进行访问。
此外,可以在 ReportProgress 方法中提供任意对象;这允许将信息发送回父对象。然后,可以在事件处理程序中完成 UI 组件的处理,该处理程序在正确的 WPF/UI 线程上自动运行。(这同样适用于"工作完成"处理。
无需为标准 WPF 项目设置任何 STA 线程选项/属性。
在列表视图控件上调用 BiginInvoke,如下所示:
files.BeginInvoke(new Action(() => files.ItemsSource = fileItems));