/免责声明,这是我第一次使用WPF和多线程,所以如果我犯了一些大错误,请多多包涵/
所以我有一个带有Tab控件的应用程序。在其中一个选项卡中,我打算通过通常的Windows窗体宿主+ Visio Viewer activeX控件等加载visio文件。唯一的问题是,当我在文档中加载时,UI冻结了20秒(因为我正在加载相当大的文件)。如我所读,这是因为我的应用程序在一个简单的线程上运行。因此,我试图实现一个后台工作程序,以在后台线程运行时保持UI处于活动状态。
实例化UserControl时,我将其添加到选项卡(Initialpath是visio文件的文件路径):
BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += Worker_DoWork;
worker.RunWorkerCompleted += Worker_RunWorkerCompleted;
worker.RunWorkerAsync(initialpath);
private void Worker_DoWork(object sender,DoWorkEventArgs e)
{
DiagramView UCworker;
UCworker = new DiagramView((string)e.Argument);
e.Result = UCworker;
}
private void Worker_RunWorkerCompleted(object sender,RunWorkerCompletedEventArgs e)
{
UC = (DiagramView)e.Result;
this.Host.Child = UC;
}
当它创建新的DiagramView时:
public DiagramView(string path)
{
InitializeComponent();
this.Resize += new EventHandler(this.UpdateSize);
this.viewer = new AxVisioViewer.AxViewer();
this.Controls.Add(this.viewer);
this.viewer.CreateControl();
this.viewer.Load(path);
this.viewer.HighQualityRender = false;
this.viewer.BackColor = Color.White;
this.viewer.PagetabsVisible = true;
this.viewer.ContextMenuEnabled = false;
this.viewer.PropertyDialogEnabled = false;
this.viewer.ToolbarVisible = true;
this.viewer.OnSelectionChanged += Viewer_OnSelectionChanged;
}
对于这一行:
this.viewer = new AxVisioViewer.AxViewer();
我得到:' activeX控件'f8cf7a98-2c45-4c8d-9151-2d716989ddab'无法实例化,因为当前线程不在单线程单元中。'
我了解到背景工作人员无法修改UI元素(如果我输入错了,请纠正我)
我也看到了这个线程:Single-threaded apartment - cannot instantiate ActiveX control
但是我不确定如何实现它(这是STA公寓状态的业务),当我尝试打开文档时,visio查看器简单崩溃了。
我需要一些指导方针来解决这个问题,因为我的目标是要让加载页面与动画一起显示,直到文档完成加载/渲染,以便我可以显示它。
预先感谢您的回答。
更新:我还尝试了以下方法:
public partial class TabDiagramView : UserControl,INotifyPropertyChanged
{
public delegate void DisplayVisio(DiagramView view);
public DisplayVisio DelegateM;
DiagramView UC;
public TabDiagramView()
{
InitializeComponent();
DelegateM = new DisplayVisio(DisplayV);
Thread t = new Thread(RT);
t.SetapartmentState(ApartmentState.STA);
t.IsBackground = true;
t.Start();
}
#region Thread
private void RT()
{
DiagramView UCworker;
UCworker = new DiagramView(initialpath);
Dispatcher.Invoke(DelegateM,UCworker);
}
private void DisplayV (DiagramView DiagV)
{
UC = DiagV;
this.Host.Child = DiagV;
}
但是在这种情况下,当我使用DisplayV方法时,会在UC和this.Host.chilld = DiagV上收到以下消息:System.InvalidOperationException:'跨线程操作无效:从线程访问的控件''而不是创建它的线程。”