附加Visual Studio调试器时await/async操作性能骤降问题求助
VS2022调试EF Core异步查询性能暴跌的问题排查与解决建议
问题现象
全新安装Visual Studio 2022社区版后,排查EF Core导入器性能问题时发现:
- 使用
FirstOrDefaultAsync异步查询时,附加调试器运行每个搜索线程耗时17-18秒,但不附加调试器时耗时不足1秒。 - 改用同步方法
FirstOrDefault后,无论是否附加调试器,线程耗时均小于1秒。 - 已尝试禁用“调试时启用诊断工具”,无明显改善。
复现测试代码
public class TestItem { [Key] public Guid Id { get; set; } public int TestNum { get; set; } } public class AppDbContext : DbContext { public DbSet<TestItem> TestItems { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseNpgsql("Host=localhost;Database=efdebugtest;Username=postgres;Password=..."); protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<TestItem>().HasIndex(r => r.TestNum); } } internal class Program { static async Task Main(string[] args) { void L(string str) => Console.WriteLine(str); using var ctx = new AppDbContext(); await ctx.Database.EnsureDeletedAsync(); await ctx.Database.MigrateAsync(); var sw = new Stopwatch(); sw.Start(); var items = Enumerable.Range(0, 100_000).Select(i => new TestItem() { Id = Guid.NewGuid(), TestNum = i, }); L($"Items Generated: {sw.Elapsed.TotalSeconds}s"); sw.Restart(); await ctx.AddRangeAsync(items); L($"Items Added: {sw.Elapsed.TotalSeconds}s"); sw.Restart(); await ctx.SaveChangesAsync(); L($"Items Saved: {sw.Elapsed.TotalSeconds}s"); ConcurrentBag<int> foundItems = new(); var testChunks = Enumerable.Range(0, 200_000).OrderBy(_ => Guid.NewGuid()).Take(20_000).Chunk(2500); await Parallel.ForEachAsync(testChunks, async (chunk, cancellationToken) => { using var threadCtx = new AppDbContext(); var threadSw = new Stopwatch(); threadSw.Start(); foreach (var num in chunk) { var dbEntry = await threadCtx.TestItems.FirstOrDefaultAsync(ti => ti.TestNum == num); if (dbEntry != null) { foundItems.Add(dbEntry.TestNum); } } L($"Thread finished search: {threadSw.Elapsed.TotalSeconds}s"); }); } }
性能对比
- 附加调试器输出:
Items Generated: 0.0003297s Items Added: 0.6718225s Items Saved: 4.2752014s Thread finished search: 17.2668618s Thread finished search: 17.2820979s ... Thread finished search: 17.4786316s Thread finished search: 17.4891402s
- 不附加调试器输出:
Items Generated: 0.0002435s Items Added: 0.6201017s Items Saved: 4.025146s Thread finished search: 0.8171215s Thread finished search: 0.8336687s ... Thread finished search: 0.8410876s Thread finished search: 0.8419168s
调试器设置调整方案
以下是针对VS2022调试器的设置调整,可解决异步查询性能暴跌问题:
禁用“仅我的代码”
路径:工具 -> 选项 -> 调试 -> 常规,取消勾选「启用仅我的代码」。
调试器跟踪异步代码时,该功能会额外加载符号并跳过非用户代码,导致异步调度开销剧增。关闭“异步调试”
路径:工具 -> 选项 -> 调试 -> 常规,取消勾选「启用异步调试」。
此设置会牺牲异步调用链的追踪能力,但能大幅降低异步调试的性能开销,适合仅需调试业务逻辑的场景。调整符号加载策略
路径:工具 -> 选项 -> 调试 -> 符号,选择「仅指定模块加载符号」,或取消勾选「Microsoft符号服务器」。
调试器加载大量系统/第三方库符号(如EF Core、Npgsql的异步相关符号)会增加CPU和IO开销,多线程异步场景下尤为明显。禁用“托管兼容模式”
路径:工具 -> 选项 -> 调试 -> 常规,取消勾选「使用托管兼容模式」。
该模式为兼容旧.NET框架设计,在.NET 6+异步场景下可能造成不必要的性能损耗。关闭调试时热重载
路径:工具 -> 选项 -> 调试 -> 热重载,取消勾选「调试时启用热重载」(若已开启)。
热重载在调试异步代码时可能注入额外检测逻辑,影响性能。
补充说明
- 上述设置可按需切换,部分设置会牺牲少量调试功能,但能让异步调试性能接近无调试器状态。
- 若需保留完整调试功能,建议将VS2022升级到最新版本,微软后续更新中修复过部分异步调试的性能问题。
内容的提问来源于stack exchange,提问作者Zak123
相关产品推荐
相关产品推荐

