EF Core 异步编程注意要点[乱入]| 8月更文挑战

547 阅读4分钟

「本文是月更第3天文章。对我来说,这是一个挑战,因此乱入一篇线程优化的文章,加油,webmote」

  • 📢欢迎点赞 :👍 收藏 ⭐留言 📝 如有错误敬请指正,赐人玫瑰,手留余香!
  • 📢本文作者:由webmote 原创,首发于 【掘金】
  • 📢作者格言: 生活在于折腾,当你不折腾生活时,生活就开始折腾你,让我们一起加油!💪💪💪

🎏 序言

不得不说,异步和线程性能问题一直是高并发的大敌。

而.net core 自从诞生就不断地提升性能,目前的.net 6有一部分也是专门在优化性能方面的开销,而最近我阅读EF Core的 RoadMap时,也欣喜的发现这个由小团队维护的类库,也开始逐步为性能的提升做出改变。

EF Core团队特别是有一段话令人惊喜: 他们将对标DapperLib库优化性能,并随.net 6一起发布。

🎏 01.EF Core 不支持在同一上下文实例上运行多个并行操作

EF Core 不支持在同一上下文实例上运行多个并行操作。 应始终等待操作完成,然后再开始下一个操作。 这通常是通过在每个异步操作上使用 await 关键字完成的。

因此不要自作聪明 不使用await ,放任操作自己执行,寄希望于异步不影响主线程。

🎏 02. 服务端与客户端异步 LINQ 运算符

为了支持异步执行 LINQ 查询,Microsoft.EntityFrameworkCore 命名空间中定义 EF Core 异步扩展方法。 EF Core 提供了一组异步扩展方法,这些方法执行查询并返回结果。 这些对应于标准的同步 LINQ 运算符包括 ToListAsync、SingleAsync、AsAsyncEnumerable 等:

var blogs = await context.Blogs.Where(b => b.Rating > 3).ToListAsync();

服务端异步 LINQ 运算符只能在 EF 查询上使用,不能将其与客户端 LINQ to Objects 查询一起使用。 若要在 EF 之外执行客户端异步 LINQ 操作,请使用 system.exception 包;此包对于在客户端上执行无法在服务器上进行求值的操作时特别有用。

遗憾的是,引用 system.exception 和服务端 LINQ 运算符上出现不明确的调用编译错误;这使得难以在同一项目中使用 EF 和 System.object。 若要解决此问题,请将 AsQueryable 添加到 DbSet:

var groupedHighlyRatedBlogs = await context.Blogs
    .AsQueryable()
    .Where(b => b.Rating > 3) // server-evaluated
    .AsAsyncEnumerable()
    .GroupBy(b => b.Rating) // client-evaluated
    .ToListAsync();

🎏 03. 并行异步数据库连接方法慢或阻塞

如果最小并发池子数没被设置,则会导致异步连接变慢,同步连接几乎不受影响,因此,默认构建sql连接字符串时,增加最小池子数参数。

  • 添加一个MinPoolSize为100的连接字符串。如果你加的数字大于100,你需要改变MaxPoolSize,因为其默认值为100,且不能小于MinPoolSize的值。

  • 对于池连接,请在你的连接字符串中添加Pooling=true,在你的非池连接中添加Pooling=false

🎏 04. 异步读取大数据(二进制,文本,图片)非常慢

异步读取10MB的VARBINARY(MAX)值大约需要5秒,而同步读取相同的值大约需要20毫秒。将数据大小增加到20MB将使运行时间增加到大约52秒。

是的,这个问题,目前换没有解决,其涉及到 Zero Copy问题以及其他的一些线程协调问题,因此,估计Ef Core 6之前是不可能被解决的,因此最好的方案是 暂时使用同步方法

🎏 05.连接池到底设置多大?

严格来说,这不是EF的问题,数据库连接池是client方面的事情,不过也是困惑我很久的问题,这里给出答案。

参考值: 连接数 = ((核心数 * 2) + 有效磁盘数)

这一公式不仅适用于数据库连接池的计算,大部分涉及计算和I/O的程序,线程数的设置都可以参考这一公式。

因此微软默认的池子数是10-100。而由于对线程的管理不善,我们的应用一般会设置 100-1000左右,哈哈,这就是控制的差距。

我们经常见到一些小规模的web应用,应付着大约十来个的并发用户,却使用着一个100连接数的连接池。这会对你的数据库造成极其不必要的负担。

🎏 06. 小结

晚上有事情,只能上班的时候抽空总结下。

养成一个好习惯,需要不停的激励和鼓励,写作的能力也许就是不断的写中提升的,当然还有自身的额能力,在不断的输出过程中,发现自己的不足以及巩固自己的知识。

30天不停更,目标很远大,今天是第三天,加油!

例行小结,理性看待!

结的是啥啊,结的是我想你点赞而不可得的寂寞。😳😳😳

👓都看到这了,还在乎点个赞吗?

👓都点赞了,还在乎一个收藏吗?

👓都收藏了,还在乎一个评论吗?