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;
由于文件的大小,该过程需要一些时间,因此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;
    }
这解决了什么,因为所有耗时的操作都保留在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;
  } 
我有一个例外:调用线程无法访问此对象,因为另一个线程拥有它.(在加载的UserControl中还有其他控件可能会出错)
有没有办法以这样的方式执行此操作UI要响应?
让XAML加载后台线程本质上是一个非首发.WPF组件具有线程亲和性,通常只能从创建它们的线程中使用.因此,在后台线程上加载会使UI响应,但会创建无法插入UI线程的组件.
您在这里拥有的最佳选择是将XAML文件分解为更小的片段,并在UI线程中逐步加载它们,确保在每次加载操作之间允许消息泵.可能BeginInvoke在Dispatcher对象上使用来安排负载.  
| 归档时间: | 
 | 
| 查看次数: | 2376 次 | 
| 最近记录: |