写代码和做菜有点像,火候到了才好吃,资源也得省着用。在实际的 .NET 项目里,性能问题经常是“平时看不出来,一上量就崩”——要么响应慢得让人着急,要么并发一高就卡死。无论在哪儿的开发团队,优化 C# 应用的性能,直接关系到用户体验、系统能扛多大流量,还有云账单上的数字。性能说白了,就是让程序用更少的资源、更短的时间,把该干的活干完。


1. 用 async/await 做异步编程

异步编程说白了就是不让线程闲着:遇到网络请求、数据库查询这种耗时活儿,线程不会死等,而是转身去处理别的请求。要是用同步方式写,一个线程就被焊死在那儿,来再多请求也只能排队干着急。

错误示范

// 阻塞调用,白白占着一个线程
var result = httpClient.GetStringAsync(url).Result;

正确打开方式

public async Task<string> GetDataAsync()
{
    return await httpClient.GetStringAsync("https://api.example.com/data");
}

在 ASP.NET Core 里这么做尤其重要:每个请求不再独占线程,线程能反复“复用”处理不同请求,并发能力自然就上去了①。


2. 数据库查询别太“豪放”

性能瓶颈十有八九出在数据库身上。常见问题有:一把拉回所有字段、该建的索引没建、不分页直接拖几千行数据。

低效写法

var users = context.Users.ToList(); // 全表全字段,一股脑全拉回来

高效写法

var users = context.Users
    .Where(u => u.IsActive)
    .Select(u => new { u.Id, u.Name }) // 只取用得到的字段
    .Skip((page - 1) * pageSize)
    .Take(pageSize)
    .ToList();

配合 SQL Server 的索引,加上 EF Core 里 AsNoTracking()(只读场景专用),能减少内存占用和 I/O 开销②。


3. 把该缓存的东西缓存起来

缓存就是把热点数据先存一份,省得每次都用库。比如新闻首页的数据,5 分钟刷新一次就够了:

if (!_cache.TryGetValue("news", out List<Article> articles))
{
    articles = await _db.Articles.Take(20).ToListAsync();
    _cache.Set("news", articles, TimeSpan.FromMinutes(10));
}
return articles;
  • 内存缓存IMemoryCache):单机应用用这个就够了;

  • 分布式缓存(Redis):多实例部署时用,不同节点能共享缓存③。


4. 内存别随便浪费

频繁在堆上创建对象,GC 就得隔三差五来回收,回收时还会“暂停世界”(Stop-The-World)。能少建对象就少建,用完了也及时释放:

// 正确:用 using 确保资源释放
using var stream = new FileStream(path, FileMode.Open);
// 处理文件

对于超过 85KB 的大对象,最好复用缓冲区,或者用 ArrayPool<T> 来减少大对象堆(LOH)的压力④。


5. 别在异步里干同步的活儿

在异步方法里用 .Result 或 .Wait(),不仅阻塞线程,还可能引发死锁:

// 危险:容易死锁
var data = GetDataAsync().Result;

// 安全:全程异步
var data = await GetDataAsync();

特别是在 ASP.NET Core 里,阻塞调用会拖垮线程池,让整个服务无法响应新请求⑤。


6. 数据结构选对了,事半功倍

不同的数据结构有各自的脾气:

  • **List<T>**:适合小规模遍历;

  • **Dictionary<TKey, TValue>**:适合 O(1) 的快速查找。

// 高效:哈希查找
var userDict = new Dictionary<int, User>();
if (userDict.TryGetValue(id, out var user)) { /* ... */ }

// 低效:线性扫描
var userList = new List<User>();
var user = userList.FirstOrDefault(u => u.Id == id);

选对数据结构,查找可以从 O(n) 降到 O(1),性能天差地别⑥。


7. LINQ 也怕“铺张浪费”

LINQ 写起来爽,但一不小心就可能产生多次遍历和中间集合:

// 低效:遍历了两次
var result = list.Where(x => x.IsActive).ToList()
                 .Where(x => x.Age > 18).ToList();

// 高效:一次遍历搞定
var result = list.Where(x => x.IsActive && x.Age > 18).ToList();

别在循环里动不动就 ToList(),能用 IQueryable 延迟执行的地方尽量用⑦。


8. 并行处理不是万能的

Parallel.ForEach 适合 CPU 密集型任务,比如批量处理图片、跑数值计算:

Parallel.ForEach(images, img => ProcessImage(img));

但线程不是越多越好,创建太多线程反而增加调度开销,性能可能不升反降。用 ParallelOptions 限制一下并发度:

var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount };
Parallel.ForEach(data, options, item => Process(item));

9. 优化之前,先拿数据说话

没有测量,就没有优化。常用的工具有:

  • BenchmarkDotNet:做微基准测试;

  • Visual Studio Profiler:分析 CPU、内存;

  • Application Insights:监控生产环境。

重点关注那些被频繁调用的方法、内存分配的热点、慢查询。有时候一个被调用百万次的小函数,比一个复杂的大计算影响更大。


10. 升级 .NET 版本,躺赚性能

新版本 .NET 在性能上一直在进步:

  • **.NET 6+**:引入 Native AOT,启动速度能快 10 倍;

  • .NET 8:GC、HTTP 栈、JSON 序列化都有优化;

  • .NET 9/10:内存占用更低,延迟更小。

从 .NET Framework 迁移到 .NET 8,往往能换来 2–5 倍的吞吐量提升。


性能优化的价值与风险

优化带来的好处

  • 响应时间从秒级降到毫秒级;

  • 云服务器成本降 30% 以上;

  • 用户不卡顿,留得住。

忽视的代价

  • 高并发下服务直接雪崩;

  • 数据库连接池被占满;

  • 用户因为慢而离开。


总结

C# 应用性能优化不是改一两处代码就能成的,它是个系统工程:找到瓶颈 → 针对性下手 → 验证效果。从异步 I/O、数据库优化,到缓存、内存管理,每一步改进都是积累。在云原生时代,性能不只是技术指标,它直接决定了你能接住多少流量、省下多少成本。


C# 性能优化技术关系图

Image

这张图想说的是:性能优化得多个角度一起抓——异步和非阻塞让 I/O 不空转,数据库和缓存把后端压力降下来,内存和数据结构把计算效率提上去,并行和版本升级把硬件潜力榨出来,而性能分析始终贯穿其中,让每次优化都有方向


参考资料

① Microsoft. Asynchronous Programming with async and await. https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/
② Microsoft. EF Core Performance Best Practices. https://learn.microsoft.com/en-us/ef/core/performance/
③ Microsoft. Caching in .NET Applications. https://learn.microsoft.com/en-us/dotnet/core/extensions/caching
④ Microsoft. Fundamentals of Garbage Collection. https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals
⑤ Stephen Toub. The dangers of async void. https://devblogs.microsoft.com/pfxteam/the-dangers-of-async-void/
⑥ Microsoft. Choosing the Right Collection Class. https://learn.microsoft.com/en-us/dotnet/standard/collections/

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐