XJo*_*neX 0 c# asynchronous async-await
我读过几篇文章,但我很难理解这一点。我试图在加载一些数据时保持 MAUI 应用程序的 UI 更新。
我想完成这个:
async public DataService()
{
//initialize stuff here
await this.GetPayees();
await this.GetCategories();
return;
}
Run Code Online (Sandbox Code Playgroud)
我读到你不能有异步构造函数,所以我不得不重做如何初始化我的类。
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;
}
Run Code Online (Sandbox Code Playgroud)
这对我的代码产生了连锁效应。我必须将返回类型更改为任务,并使其他方法异步
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;
}
Run Code Online (Sandbox Code Playgroud)
我收到编译器关于在最后两种方法中没有等待的警告。我真的会等待所有的 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
});
}
}
Run Code Online (Sandbox Code Playgroud)
我是否以错误的方式处理这个问题?尝试采用 async/await 实际上会毁掉我的项目。
该async关键字仅允许使用await. 如果你不需要使用await,那么你就不需要async。
List.Add()不是异步方法,因此您不会使用await. 所以只需删除async关键字即可;你不需要它。
当 CPU 必须等待外部资源时,异步编程很有用,例如:网络请求、文件存储请求等 - 任何不在 CPU 或 RAM 内部的资源。将对象添加到集合纯粹是内存中操作,因此不太适合异步编程。
我认为阅读 Microsoft 关于使用 async 和 wait 进行异步编程的文档会让您受益匪浅。写得相当好。
更新:
既然您说对的调用Add()只是 SQL 访问的占位符,那么是的,您希望用于asyncSQL 调用,并且您的做法是正确的:创建一个public static async方法来为您创建该类的实例。这称为“工厂方法”。您甚至可以更进一步,将构造函数设为私有,这样您就可以强制使用工厂方法:
private DataService() {}
public static async Task<DataService> BuildDataServiceAsync()
{
var dataService = new DataService();
await dataService.GetPayees();
await dataService.GetCategories();
return dataService;
}
Run Code Online (Sandbox Code Playgroud)
GetPayees()如果GetCategories()必须调用私有构造函数才能使对象处于可用状态,则拥有私有构造函数非常重要。
| 归档时间: |
|
| 查看次数: |
55 次 |
| 最近记录: |