【发布时间】:2022-11-18 00:13:10
【问题描述】:
我已经阅读了几篇文章,但我很难理解这一点。我试图在加载一些数据时保持我的 MAUI 应用程序的 UI 更新。
我想完成这个:
async public DataService()
{
//initialize stuff here
await this.GetPayees();
await this.GetCategories();
return;
}
我读到你不能有一个异步构造函数,所以我不得不重做我如何初始化我的类。
public DataService()
{
//Take this out here
//this.GetPayees();
//this.GetCategories();
return;
}
async public static Task<DataService> BuildDataServiceAsync()
{
//await them here
var dataService = new DataService();
await dataService.GetPayees();
await dataService.GetCategories();
return dataService;
}
这在我的代码中产生了级联效应。我必须将返回类型更改为任务,并使其他方法异步
async public Task<List<Payee>> GetPayees()
{
//Load arbitrary data,
if(Payees.Count != 0) return Payees;
Payees.Add(new Payee { Id = 0, Name = "Food Lion", DefaultCategoryId = 0, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 1, Name = "Work Incorporated", DefaultCategoryId = 1, DefaultIsCredit = true });
Payees.Add(new Payee { Id = 2, Name = "Hardees", DefaultCategoryId = 3, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 3, Name = "Wal-Mart", DefaultCategoryId = 5, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 4, Name = "Aldis", DefaultCategoryId = 0, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 5, Name = "McDonalds", DefaultCategoryId = 3, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 6, Name = "Harris Teeter", DefaultCategoryId = 0, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 7, Name = "Shoe Show", DefaultCategoryId = 2, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 8, Name = "Capital One", DefaultCategoryId = 4, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 9, Name = "Dicks Sporting Goods", DefaultCategoryId = 6, DefaultIsCredit = false });
Payees.Add(new Payee { Id = 10, Name = "Amazon", DefaultCategoryId = 7, DefaultIsCredit = false });
return Payees;
}
async public Task<List<Category>> GetCategories()
{
if(Categories.Count != 0) return Categories;
Categories.Add(new Category { Id = 0, Name = "Groceries" });
Categories.Add(new Category { Id = 1, Name = "Paycheck" });
Categories.Add(new Category { Id = 2, Name = "Shoes" });
Categories.Add(new Category { Id = 3, Name = "Fast Food" });
Categories.Add(new Category { Id = 4, Name = "Credit Card" });
Categories.Add(new Category { Id = 5, Name = "Supplies" });
Categories.Add(new Category { Id = 6, Name = "Recreation" });
Categories.Add(new Category { Id = 7, Name = "Grocery" });
Categories.Add(new Category { Id = 8, Name = "Gross" });
Categories.Add(new Category { Id = 9, Name = "Grass" });
return Categories;
}
我收到关于在最后两种方法中没有等待的编译器警告。我真的会等待所有的 Add() 吗?
我只是让依赖注入按照我想要的方式工作,但这一切都级联回我的视图模型,它注入了我的依赖项:
public PayeesViewModel(DataService dataService, NavigationService navigationService, ValidationService validationService)
{
this.dataService = dataService;
this.navigationService = navigationService;
this.validationService = validationService;
Payees = await dataService.GetPayees();
Categories = await dataService.GetCategories();
for(int x = 0; x < Payees.Count; x++)
{
PayeeDisplay.Add(new PayeeDisplay
{
Id = Payees[x].Id,
Name = Payees[x].Name,
DefaultCategory = Categories.Find(c => c.Id.Equals(Payees[x].DefaultCategoryId)).Name,
DefaultCategoryId = Payees[x].DefaultCategoryId,
DefaultIsCredit = Payees[x].DefaultIsCredit
});
}
}
我会以错误的方式解决这个问题吗?尝试采用 async/await 简直就是在毁掉我的项目。
【问题讨论】:
-
为什么把
GetPayees和GetCategories改成返回任务?它们不包含任何异步代码?或者这些模型是 Stack Overflow 并且这些方法实际上是异步调用数据库之类的吗? -
构造函数不能是异步的,工厂方法可以……但是你不应该尝试在任何构造函数中做 CPU 或 I/O 繁重的工作。您应该在您的视图操作中调用一些异步方法,而不是您的模型构造器。
-
@ProgrammingLlama 我的印象是如果你想在一个方法上使用
await,那个方法也需要是async,然后返回一个任务。目前在我的应用程序开发中,我只是创建列表并使用占位符数据,直到我开始实施 SQLite。我想首先充实 UI 和业务逻辑。 :) -
async允许您在方法中使用await。您可以创建一个返回Task而不返回async的方法。如果您没有什么可等待的,那么您可能不想创建一个async/ 返回Task的方法,除非您符合接口或抽象方法。等待返回 Task 的方法也不一定使其异步。如果一个方法实际上没有做一些异步的事情,那么它可能无论如何都会同步运行。
标签: c# asynchronous async-await