聊聊 C# 中 using 语句可能的 3 个陷阱

简介: 大家都知道,C# 中可以用 using 关键字来简化非托管资源(如文件流、数据库连接等)的释放,但是如果用在错误的使用场景,可能会带来一些意想不到又难以排查的问题,来看看有哪些可能的陷阱吧!

Coding-74.png

前言

大家都知道,C# 中可以用 using 关键字来简化非托管资源(如文件流、数据库连接等)的释放,当变量离开 using 作用的范围后,会自动调用对象的 Dispose 方法,从而完成非托管资源的释放。在 C#8.0,进一步引入了简化版的 "using声明" 语法来避免多个 using 语句的嵌套,保证代码的优美,例如:

string connStr = "......";

using var conn = new SqlConnection(connStr);

conn.Open();

using var cmd = conn.CreateCommand();

cmd.CommandText = "select * from testdb";

using var reader = cmd.ExecuteReader();

while (reader.Read())
{
   
    // ......
}

虽然 using 语句非常有用,但在实际使用过程中也存在一些潜在的问题,不可不察!

可能的陷阱

  1. 嵌套使用 using 语句

    当多个 using 语句嵌套在一起,内部 using 语句中的资源在释放时,可能会把外部 using 语句中的资源也释放掉,比如:

     using (Stream stream = new FileStream("d:\1.txt", FileMode.OpenOrCreate))
     {
         
         using (StreamWriter writer = new StreamWriter(stream))
         {
         
             // ......
         }
     }
    

    例子中当内部的 writer 释放时,会同时释放外部的 stream 对象,这是因为 StreamWriter 类型 Dispose 机制所造成,所以当我们不太清除内层对象是否与外层对象有关系时,尤其要慎用 using 语句。

    除此之外,外部的 using 有时候也可能会在内部的 using 结束前就释放资源,导致意外的问题发生,比如数据库连接。

  2. 资源释放顺序:

    当多个 using 语句嵌套在一起时,如果多个资源需要按照特定顺序释放时,using 语句可能无法保证这一顺序,导致意外的问题发生。

  3. 作用域:

    简化版的 "using声明" 语法默认的作用域是整个方法体,所以很容易导致意外的问题发生,比如以下代码:

     void usingTest() 
     {
         
         using var outStream = File.OpenWrite("d:/1.txt");
         using var writer = new StreamWriter(outStream);
         writer.WriteLine("Hello world");
         string s = File.ReadAllText("d:/1.txt");
         Console.WriteLine(s);
     }
    

    当代码执行到下面这行代码时,就会提示文件被占用的错误。

     string s = File.ReadAllText("d:/1.txt");
    

    需要记得用花括号 {}using 语句包起来才能避免这个问题,如:

     void usingTest() 
     {
         
         {
         
             using var outStream = File.OpenWrite("d:/1.txt");
             using var writer = new StreamWriter(outStream);
             writer.WriteLine("Hello world");
         }
         string s = File.ReadAllText("d:/1.txt");
         Console.WriteLine(s);
     }
    

总结

using 语句本质上是 try-finally 的语法糖,所以当多个 using 语句嵌套在一起的时候,实际上就是多个 try-finally 语句嵌套在一起,所以造成一些奇怪的问题也就不奇怪了,尤其是 C#8.0 进一步简化 using 语句之后。

我们在享受 using 语句带来的便利的同时,也要注意 using 语句正确的使用场景,尤其是在需要使用嵌套 using 语句的时候,这样才能提高程序的健壮性。

最后,using 语句除了用于释放非托管资源之外,还在其它的用途,比如引用命名空间、为命名空间或类型创建别名等,有兴趣的童鞋可以继续深入了解。

我是老杨,一个执着于编程乐趣、至今奋斗在一线的 10年+ 资深研发老鸟,是软件项目管理师,也是快乐的程序猿,持续免费分享全栈实用编程技巧、项目管理经验和职场成长心得。喜欢文章欢迎关注老杨的公众号,和你共同探索代码世界的奥秘!

相关文章
|
存储 SQL Oracle
时空数据库有哪些
时空数据库有哪些
|
人工智能 Nacos 开发者
Nacos 开源 MCP Router,加速 MCP 私有化部署
Nacos MCP Router 发布全新版本。带来了多项重要更新,包括对 SSE 和 StreamableHTTP 协议的全面支持、Docker 容器化部署方案以及革命性的 MCP Server 协议一键转换功能。文章中详细的介绍更新内容并简单演示了使用过程。Nacos MCP Router 新版本的发布,不仅提升了开发者的使用体验,也为 MCP 服务的广泛应用和生态繁荣奠定了基础,欢迎关注。
2059 63
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
647 2
Apple Push Services不受信任解决方法
Apple Push Services不受信任解决方法
753 59
|
数据采集 JSON API
.NET 3.5 中 HttpWebRequest 的核心用法及应用
【9月更文挑战第7天】在.NET 3.5环境下,HttpWebRequest 类是处理HTTP请求的一个核心组件,它封装了HTTP协议的细节,使得开发者可以方便地发送HTTP请求并接收响应。本文将详细介绍HttpWebRequest的核心用法及其实战应用。
898 6
|
11月前
|
安全 IDE Java
【分享排雷经历】系统引入Apache-Tika产生的NoClassDefFoundError错误
为实现文件导入的安全控制,在系统中引入了基于`Apache Tika`的文件类型校验机制。但在运行时出现`NoClassDefFoundError`,提示缺少`commons-io`类。经排查发现,`monorepo`依赖的`commons-io`版本(2.6)低于Tika 2.9.1所需版本(2.16.1)。由于系统依赖统一管理,直接升级`commons-io`可能影响其他模块。最终解决方案为降级Tika版本至2.4.1,该版本兼容`commons-io:2.6`,问题得以解决且功能满足需求。
623 0
|
存储 缓存 物联网
MNN推理框架将大模型放进移动端设备,并达到SOTA推理性能!
随着移动端(手机/平板等)算力、内存、磁盘空间的不断增长,在移动端部署大模型逐渐成为可能。在端侧运行大模型,可以有一系列好处:去除网络延迟,加快响应速度;降低算力成本,便于大规模应用;不需数据上传,保护用户稳私。
3145 13
MNN推理框架将大模型放进移动端设备,并达到SOTA推理性能!
|
网络协议 Dubbo 应用服务中间件
实操指南:Postman 怎么调试 WebSocket
WebSocket 是一个支持双向通信的网络协议,它在实时性和效率方面具有很大的优势。Postman 是一个流行的 API 开发工具,它提供了许多功能来测试和调试 RESTful API 接口,最新的版本也支持 WebSocket 接口的调试。想要学习更多关于 Postman 的知识,可访问 Postman 中文文档。在本文中,我们将介绍如何使用 Postman 调试 WebSocket 接口。
|
安全 Windows
关于如何打开IIS管理器
关于如何打开IIS管理器
1101 3
|
NoSQL 数据挖掘 定位技术
如何让geopandas支持写出gdb文件
如何让geopandas支持写出gdb文件
798 4

热门文章

最新文章