一文看懂"async"和“await”关键词是如何简化了C#中多线程的开发过程
当我们使用需要长时间运行的方法(即,用于读取大文件或从网络下载大量资源)时,在同步的应用程序中,应用程序本身将停止运行,直到活动完成 。在这些情况下,异步编程非常有用:它使我们能够并行执行不同任务,并在需要时等待其完成 。
这种方法有许多不同的模型类型:APM(异步编程模型),基于事件(异步模型EAP),以及TAP,基于任务的(异步模型任务) 。让我们看看如何使用关键字async和await在C#中实现第三个方法 。
编写异步代码的主要问题之一是可维护性:实际上,许多人普遍认为这种编程方法会使代码复杂化 。幸运的是,C#5引入了一种简化的方法,在该方法中,编译器运行由开发人员先前完成的艰巨任务,并且应用程序保留类似于同步代码的逻辑结构 。
让我们举个例子 。假设我们有一个.NET Core项目,我们应该在其中管理三个实体:Area,Company和Resource 。
public class Area
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
}
public class Company
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
}
public class Resource
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
}
现在假设我们应该使用Entity Framework Core将这些实体的值保存在数据库中 。其DbContext是:
public class AppDbContext : DbContext
{
public DbSet<Area> Areas { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Resource> Resources { get; set; }
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) {}
override protected void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Area> .HasData(
new Area { Id = 1, Name = "Area1"},
new Area { Id = 2, Name = "Area2"},
new Area { Id = 3, Name = "Area3"},
new Area { Id = 4, Name = "Area4"},
new Area { Id = 5, Name = "Area5"});
modelBuilder.Entity<Company> .HasData(
new Area { Id = 1, Name = "Company1"},
new Area { Id = 2, Name = "Company2"},
new Area { Id = 3, Name = "Company3"},
new Area { Id = 4, Name = "Company4"},
new Area { Id = 5, Name = "Company5"});
modelBuilder.Entity<Resource>.HasData(
new Area { Id = 1, Name = "Resource1"},
new Area { Id = 2, Name = "Resource2"},
new Area { Id = 3, Name = "Resource3"},
new Area { Id = 4, Name = "Resource4"},
new Area { Id = 5, Name = "Resource5"});
}
}
从代码中可以看到,我们插入了一些示例数据进行处理 。现在假设我们要使用Controller API公开这些数据,既单独(针对每个实体),又使用将它们全部联接在一起的方法,并通过一次调用返回它们 。
使用同步方法,Controller API 将是:
[ApiController]
[Route("[controller]")]
public class DataController : ControllerBase
{
private readonly AppDbContext db = ;
public DataController(AppDbContext db)
{
this.db = db;
}
public IActionResult Get
{
var areas = this.GetAreas;
var companies = this.GetCompanies;
var resources = this.GetResources;
return Ok(new { areas = areas, companies = companies, resources = resources });
}
[Route("areas")]
public Area GetAreas
{
return this.db.Areas.ToArray;
}
[Route("companies")]
public Company GetCompanies
{
return this.db.Companies.ToArray;
}
[Route("resources")]
public Resource GetResources
{
return this.db.Resources.ToArray;
}
}
Get方法在其中调用返回单个结果的三个方法,并等待每个方法的执行完成后再传递到下一个结果 。这三种方法互不相关,因此您无需等待其中一种方法的执行即可调用另一种方法 。然后,您可以创建三个独立的任务以并行执行 。
推荐阅读
- 一文看懂“超融合”和“虚拟化”的区别
- 爷青回!经典老牌音乐播放器Winamp宣布回归
- IOS技术分享|WebRTC iOS源码下载&编译
- 一张图看懂私域流量的底层逻辑
- 详解Python软件安装教程和配置,小白都能看懂的教程,值得收藏
- 一文告诉你USB4和雷雳4到底是什么
- 百度SEO搜索引擎优化为什么会提倡"白帽"拒绝"黑帽"
- 看懂IPv6+,这篇就够了
- 不要让爱你的觉得不值?我的爱对你来说一文不值
- 微信朋友圈使用"提醒谁看"时,别人能看到吗?