WPF加载帧异步

本文关键字:异步 加载 WPF | 更新日期: 2023-09-27 18:02:50

我有一个TabConrol,当用户做某些事情时,一个新的TabItem以编程方式添加。在这个选项卡中有一个框架,它将包含所需的Page.XAML

private void addNewTab()
{
   TabItem tab = new TabItem();
   Grid g = new Grid();
   Frame f = newFrame();
   g.Children.Add(f);
   tab.Content = g;
   MyTabControl.Items.Add(tab);
   MyTabControl.SelectedItem = tab;
}
private Frame newFrame()
{
   Frame f = new Frame();
   //Full logic for Frame removed
   f.Navigate(new MyPage());
   return f;
}

问题是有时加载新的Frame可能需要一些时间。所以我想用async。当它加载的时候会有一个加载动画。我想这是可行的;

private async void addNewTab()
{
   TabItem tab = new TabItem();
   Grid g = new Grid();
   var test = Task<Frame>.Factory.StartNew(() => newFrame(selectTab, value));
   await test;
   f = test.Result;
   g.Children.Add(f);
   tab.Content = g;
   MyTabControl.Items.Add(tab);
   MyTabControl.SelectedItem = tab;
}
private Frame newFrame()
{
   Frame f = new Frame();
   //Full logic for Frame removed
   f.Navigate(new MyPage());
   return f;
}

问题是它在运行newFrame()时在Frame f = new Frame();上返回以下错误;

类型为'System '的异常。InvalidOperationException'发生在PresentationCore.dll,但未在用户代码中处理

附加信息:调用线程必须是STA,因为许多UI组件需要这个

开始认为我试图用错误的方式解决这个问题。处理这个问题的最好方法是什么?

WPF加载帧异步

构建任何合理的UI都是一个非常快的操作。但是,确定要在该UI中显示的数据可能需要花费任何时间。所以我认为这才是真正的慢。

你不能在后台线程上构建实际的UI组件;这就是异常告诉你的。

但是你可以在后台线程中构建data然后将加载到UI:

private async Task addNewTabAsync()
{
  TabItem tab = new TabItem();
  Grid g = new Grid();
  var data = await Task.Run(() => getData(value));
  Frame f = new Frame();
  // Fill out frame with data.
  f.Navigate(new MyPage());
  g.Children.Add(f);
  tab.Content = g;
  MyTabControl.Items.Add(tab);
  MyTabControl.SelectedItem = tab;
}

请注意,我将async void更改为async Task(并添加了Async后缀),并将StartNew更改为Run以遵循最佳实践。