在UWP中使用Caliburn.Micro从构造函数调用异步方法

时间:2015-11-26 08:40:57

标签: c# caliburn.micro uwp

我有以下ViewModel结构:

  • App.xaml.cs
    • MainViewModel
      • DetailViewModel

我通过以下代码在MainViewModel和DetailViewModel之间导航:

navigationService.For<DetailViewModel>().Navigate();

它是DetailViewModel的构造函数:

public DetailViewModel(INavigationService navigationService)
{
  GetData();
}

private async Task GetData()
{
  using (var context = new MyDataContext())
  {
    var result = await (from data in context.Data
                          select data).ToListAsync();
    DataList = new ObservableCollection<Data>(result);
  }
}

由于我在调用await时不使用GetData,构造函数应该非常快速地返回,并且应该在以后填充列表。

我遇到非常慢的导航,我点击了MainViewModel中的项目,GUI冻结了一秒钟,当填充列表时,我看到了详细信息(debug显示构造函数在列表完成之前完成。)

我看到一个警告说:

  

因为没有等待此调用,所以执行当前方法   在通话完成之前继续。

然后阻止什么?我还应该设置什么?

3 个答案:

答案 0 :(得分:2)

AFAIK,SQLite实体框架提供程序不支持真正的异步方法。因此,对JPA的调用实际上是同步的,导致您的延迟。

解决此问题的最佳方法是将ToListAsyncTask.Run一起使用( awaitContinueWith):

Execute.OnUIThread

请注意引入public DetailViewModel(INavigationService navigationService) { InitializeAsync(); } private async Task InitializeAsync() { try { DataList = await Task.Run(() => GetData()); } catch { // TODO: Log } } private List<Data> GetData() { using (var context = new MyDataContext()) { return context.Data.ToList(); } } / try;由于catch被视为&#34;顶级&#34;异步操作。

答案 1 :(得分:0)

用这个代替代码:

public DetailViewModel(INavigationService navigationService)
{
    Task.Run(() =>
        {
            GetData();
        });
}

private void GetData()
{
    using (var context = new MyDataContext())
    {
        var result = await (from data in context.Data
                            select data).ToListAsync();

        DataList = new ObservableCollection<Data>(result);
    }
}

答案 2 :(得分:-1)

这种方式可以按预期工作:

public DetailViewModel(INavigationService navigationService)
{
    Task.Run(() =>
        {
            GetData();
        }).ContinueWith(
      (x) =>
      {
        Execute.OnUIThread(
              () =>  DataList = new ObservableCollection<Data>(x.Result));
      });
    };
}

private Task<List<Data>> GetData()
{
    using (var context = new MyDataContext())
    {
        return await (from data in context.Data
                            select data).ToListAsync();

    }
}

感谢您的建议。