背景线程中的XamlReader.Load.可能吗?

rem*_*rem 8 c# wpf multithreading xamlreader

WPF应用程序具有使用以下XamlReader.Load()方法从单独文件加载用户控件的操作:

StreamReader mysr = new StreamReader(pathToFile);
DependencyObject rootObject = XamlReader.Load(mysr.BaseStream) as DependencyObject;
ContentControl displayPage = FindName("displayContentControl") as ContentControl;
displayPage.Content = rootObject;
Run Code Online (Sandbox Code Playgroud)

由于文件的大小,该过程需要一些时间,因此UI会冻结几秒钟.

为了保持应用程序响应,我尝试使用后台线程来执行在UI更新中不直接调用的操作部分.

BackgroundWorker我尝试使用时出现错误:调用线程必须是STA,因为许多UI组件都需要这个

所以,我走另一条路:

 private Thread _backgroundThread;
 _backgroundThread = new Thread(DoReadFile);
 _backgroundThread.SetApartmentState(ApartmentState.STA);
 _backgroundThread.Start();
 void DoReadFile()
 {
   StreamReader mysr3 = new StreamReader(path2);
   Dispatcher.BeginInvoke(
           DispatcherPriority.Normal,
           (Action<StreamReader>)FinishedReading,
           mysr3);
 }

 void FinishedReading(StreamReader stream)
    {            
        DependencyObject rootObject = XamlReader.Load(stream.BaseStream) as DependencyObject;
        ContentControl displayPage = FindName("displayContentControl") as ContentControl;
        displayPage.Content = rootObject;
    }
Run Code Online (Sandbox Code Playgroud)

这解决了什么,因为所有耗时的操作都保留在UI线程中.

当我尝试这样做时,在后台进行所有解析:

private Thread _backgroundThread;
_backgroundThread = new Thread(DoReadFile);
_backgroundThread.SetApartmentState(ApartmentState.STA);
_backgroundThread.Start();
 void DoReadFile()
 {
  StreamReader mysr3 = new StreamReader(path2);      
  DependencyObject rootObject3 = XamlReader.Load(mysr3.BaseStream) as DependencyObject;
        Dispatcher.BeginInvoke(
           DispatcherPriority.Normal,
           (Action<DependencyObject>)FinishedReading,
           rootObject3);
  }

  void FinishedReading(DependencyObject rootObject)
  {            
    ContentControl displayPage = FindName("displayContentControl") as ContentControl;
    displayPage.Content = rootObject;
  } 
Run Code Online (Sandbox Code Playgroud)

我有一个例外:调用线程无法访问此对象,因为另一个线程拥有它.(在加载的UserControl中还有其他控件可能会出错)

有没有办法以这样的方式执行此操作UI要响应?

Jar*_*Par 7

让XAML加载后台线程本质上是一个非首发.WPF组件具有线程亲和性,通常只能从创建它们的线程中使用.因此,在后台线程上加载会使UI响应,但会创建无法插入UI线程的组件.

您在这里拥有的最佳选择是将XAML文件分解为更小的片段,并在UI线程中逐步加载它们,确保在每次加载操作之间允许消息泵.可能BeginInvokeDispatcher对象上使用来安排负载.