【问题标题】:Load data (async/await)加载数据(异步/等待)
【发布时间】:2017-02-01 21:29:17
【问题描述】:

我不确定这个状态。我需要从数据库异步中获取数据。

我有类 DB

public class Db{

public async Task<ObservableCollection<Person>> GetAllPerson()
{ 
 using (var context = new Db())
 {
    // get data and return ObservableCollection<Person>  
 }
}               

}

在 ViewModel 中我调用 LoadData 函数。

public class VM{

    public ObservableCollection<Person> Person { get; set; }
private readonly DB sqlRepository;

public VM()
{
    sqlRepository=new DB();
    LoadData();
}
private async void LoadData()
    {
        Person= await sqlRepository.GetAllPerson();
    }

}

我收到警告:警告 CS1998 此异步方法缺少“等待”运算符,将同步运行。

如何异步运行我的函数? 我应该使用吗?

Person=await Task.Run(()=>this.sqlRepository.GetAllPerson());

【问题讨论】:

  • 你可以试试。我使用了一种 Person=await Task.Run(()=>this.sqlRepository.GetAllPerson());在我的项目中。
  • 我收到消息说这段代码将同步运行。
  • 警告在哪一行?
  • 在DB层开头的函数public async Task> GetAllPerson()
  • 那么您可能没有在该方法中进行任何异步调用。粘贴正在从数据库中提取数据的代码行。

标签: c# async-await


【解决方案1】:

如何异步运行我的函数?

您从错误的方向解决问题。您正在尝试“由外而内”——您的 ViewModel 想要异步加载数据库数据。这是描述问题的好方法,但解决问题的方法是错误的。

要更轻松地解决它,请从另一端开始。任何实际调用数据库的方法(例如,实体框架调用)都应该是异步的首先,然后让async 从那里生长出来。最终你会得到类似的结果:

public async Task<ObservableCollection<Person>> GetAllPersonAsync()
{ 
  using (var context = new Db())
  {
    // This code wasn't shown in the question.
    // But from the compiler warning, it was probably using something like
    //   var people = People.ToList();
    //   return new ObservableCollection<Person>(people);
    // And the async version should be:
    var people = await People.ToListAsync();
    return new ObservableCollection<Person>(people);
  }
}

可以消费:

private async void LoadData()
{
  Person = await sqlRepository.GetAllPersonAsync();
}

但我建议通过NotifyTask 使用它,如我的MVVM async data binding article 中所述。这种方法将使您能够对繁忙的微调器等进行数据绑定。

我应该使用 [Task.Run] 吗?

没有。这就是“假异步”——您的代码表现就像是异步的,但实际上只是在后台线程上同步运行。

【讨论】:

  • 对于加载数据我应该使用Task吗?
  • 对于 LoadData 我应该使用任务吗? private async void LoadData() { Person = await Task.Factory.StartNew(() =>GetAllPerson() ); }
  • @leapold:不。你不应该使用StartNewTask.Run。使用异步 EF API,例如 ToListAsync
猜你喜欢
  • 2021-07-07
  • 1970-01-01
  • 2020-09-02
  • 2023-03-15
  • 1970-01-01
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多