"The calling thread must be STA, because many UI components require this."使用 BeginInvoke 动态添加列表视图项时



我正在尝试从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));

最新更新