ViewModel创建阻止UI

时间:2016-02-05 00:15:20

标签: c# asynchronous async-await winrt-xaml uwp

在我的XAML UI中,我有一个listview,其中包含一个复杂对象列表。这些复杂的对象有一个异步初始化方法,可以加载数据(下载图像,格式化文本等)。

这是设置(伪代码):

public class PageViewModel
{
  public ObservableCollection<ItemViewModel> Items;

  public async Task InitializeAsync()
  {
      var models = await GetModelsAsync();
      List<Task> initTasks = new List<Task>();
      foreach(var model in models)
      {
         var vm = new ItemViewModel(model)
         initTasks.Add(vm.InitializeAsync());
         Items.Add(vm);
      }

      await Task.WhenAll(initTasks);
  }
}

我看到的问题是,似乎UI线程被阻止并且没有响应,直到所有任务都完成,这让我感到困惑。我所有的异步复杂逻辑都在等待着。

这引导我尝试这里唯一的其他逻辑,创建视图模型。当我在Task.Run中包装以下代码时,问题似乎消失了:

var vm = Task.Run(() => new ItemViewModel(item))

这让我感到惊讶,因为ViewModel构造函数中几乎没有逻辑,这就是我最初把它放在UI线程上的原因。

有没有人想过为什么我会在这里看到UI线程块?你有任何代码建议吗?

1 个答案:

答案 0 :(得分:0)

我无法确定你在哪里调用你的init(),但你应该(除非你使用一个自动为你调用它的智能框架)从你的Page OnNavTo覆盖调用,如下所示:

public sealed partial class MainPage : Page
{
    public MainPage() { InitializeComponent(); }

    MainPageViewModel ViewModel => DataContext as MainPage;

    protected override async void OnNavigatedTo(NavigationEventArgs e)
    {
        DataContext = new MainPageViewModel();
        await DataContext.InitAsync();
    }
}

public class MainPageViewModel
{
    public Task InitAsync()
    {
        // TODO
    }
}

另外,我不建议您并行加载模型,而是因为低功耗设备的性能而串联。合理?我不应该对您的用户产生明显的影响,如果代的成本很高,您的应用程序将无法锁定。

祝你好运!