Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/259.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WPF-使用Backgroundworker加载Visio文件_C#_Wpf_Multithreading_Visio - Fatal编程技术网

C# WPF-使用Backgroundworker加载Visio文件

C# WPF-使用Backgroundworker加载Visio文件,c#,wpf,multithreading,visio,C#,Wpf,Multithreading,Visio,/免责声明,这是我第一次使用WPF和多线程,如果我犯了一些大错误,请容忍我/ 所以我有一个带有tabcontrol的应用程序。在其中一个选项卡中,我打算通过常用的windows窗体主机+visio viewer activeX控件等加载到visio文件中。。。而且它工作得很好。唯一的问题是,当我加载文档时,UI会冻结20秒(因为我加载的是相当大的文件)。正如我所读到的,这是因为我的应用程序运行在一个简单的线程上。因此,我试图实现一个后台工作程序,以便在后台线程运行时保持UI的反应性 当我实例化U

/免责声明,这是我第一次使用WPF和多线程,如果我犯了一些大错误,请容忍我/

所以我有一个带有tabcontrol的应用程序。在其中一个选项卡中,我打算通过常用的windows窗体主机+visio viewer activeX控件等加载到visio文件中。。。而且它工作得很好。唯一的问题是,当我加载文档时,UI会冻结20秒(因为我加载的是相当大的文件)。正如我所读到的,这是因为我的应用程序运行在一个简单的线程上。因此,我试图实现一个后台工作程序,以便在后台线程运行时保持UI的反应性

当我实例化UserControl时,我会将其添加到选项卡(Initialpath是visio文件的文件路径):

当它创建新的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“无法实例化,因为当前线程不在单线程单元中。”

我了解到backgroundworker无法修改UI元素(如果我错了,请纠正我)

我还看到了这条线:

但我不知道如何实现它(这是STA公寓状态业务),当我尝试时,visio viewer simple在尝试打开文档时崩溃

我需要一些指导方针来解决这个问题,因为我的目标是在文档加载/渲染完成之前,让加载页面显示动画,以便显示它

提前感谢您的回答

更新:我还尝试了以下方法:

    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.child=DiagV上得到以下消息:System.InvalidOperationException:“跨线程操作无效:控件“”从创建它的线程以外的线程访问。”

从另一个线程加载UI控件是不可能的。但是,如果库提供了线程安全的方法(例如,
AxViewer.LoadAsync
),则可以解决冻结问题,因此让用户能够承受
viewer.Load
的唯一方法是延迟
viewer.Load
操作,直到加载窗口:

string _path;
public DiagramView(string path)
{
    InitializeComponent();

    _path = path;
   this.Resize += new EventHandler(this.UpdateSize);
   this.viewer = new AxVisioViewer.AxViewer();
   this.Controls.Add(this.viewer);
   this.viewer.CreateControl();
   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.Loaded += Viewer_Loaded;
}

private void Viewer_Loaded(object sender, RoutedEventArgs e)
{
    viewer.Load(_path);
}

更重要的是,删除后台工作代码。它在这里没有任何用处。

根本不可能从另一个线程加载UI控件。但是,如果库提供了线程安全的方法(例如,
AxViewer.LoadAsync
),则可以解决冻结问题,因此让用户能够承受
viewer.Load
的唯一方法是延迟
viewer.Load
操作,直到加载窗口:

string _path;
public DiagramView(string path)
{
    InitializeComponent();

    _path = path;
   this.Resize += new EventHandler(this.UpdateSize);
   this.viewer = new AxVisioViewer.AxViewer();
   this.Controls.Add(this.viewer);
   this.viewer.CreateControl();
   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.Loaded += Viewer_Loaded;
}

private void Viewer_Loaded(object sender, RoutedEventArgs e)
{
    viewer.Load(_path);
}

更重要的是,删除后台工作代码。它在这里没有任何用处。

如果你告诉我们你在用什么图书馆,会有帮助的?什么是AxVisioViewer.AxViewer?根本不可能从另一个线程加载UI控件。如果该库包含异步加载程序,则可以使用该方法加载而不阻塞UI线程,否则就没有luckHi了!AxVisioViewer.AxViewer只是对Visio Viewer API()的引用,创建的对象是Visio Viewer对象()。我还尝试手动创建一个线程(参见更新),正如我所说的,您不能在另一个线程中创建控件。库应该提供线程安全的方法,否则就无法实现。最接近实现它的方法是只在另一个线程中放入Load(),但我认为如果您告诉我们您使用的是什么库,这不会有帮助?什么是AxVisioViewer.AxViewer?根本不可能从另一个线程加载UI控件。如果该库包含异步加载程序,则可以使用该方法加载而不阻塞UI线程,否则就没有luckHi了!AxVisioViewer.AxViewer只是对Visio Viewer API()的引用,创建的对象是Visio Viewer对象()。我还尝试手动创建一个线程(参见更新),正如我所说的,您不能在另一个线程中创建控件。库应该提供线程安全的方法,否则就无法实现。最接近实现它的方法是在另一个线程中只放入Load(),但我认为这不起作用