首页 > 编程语言 >C# 资源回收

C# 资源回收

时间:2024-05-26 14:58:52浏览次数:15  
标签:释放 C# 托管 Dispose 回收 GC ResourceHolder 资源

在C#中,资源主要分为托管资源(Managed Resources)和非托管资源(Unmanaged Resources)。了解这两种资源的区别对于正确实现IDisposable接口和确保资源得到合理管理是非常重要的。

托管资源(Managed Resources)

托管资源是由.NET运行时直接管理的资源。这些资源通常由.NET框架提供,例如:

  • 字符串(String)
  • 数组(Array)
  • 集合(Collection)
  • 其他.NET类库对象

托管资源的生命周期由.NET垃圾回收器(Garbage Collector,GC)管理。GC会自动回收不再使用的对象,释放它们占用的内存。由于GC的存在,开发者通常不需要手动释放托管资源。

非托管资源(Unmanaged Resources)

非托管资源不是由.NET运行时管理的资源。这些资源需要程序员显式释放,例如:

  • 文件句柄(File Handles)
  • 窗口句柄(Window Handles)
  • 网络连接(Network Connections)
  • 数据库连接(Database Connections)
  • 硬件资源(Hardware Resources)

有个很典型的特征时,托管资源的资源释放流程是很标准的;而非托管资源的释放很可能只有具体的开发者才知道,比如一个网络连接在释放前可能会进行一系列特定的握手和消息通知操作,这写操作GC没法自动完成,必须开发者自己实现IDisposable接口完成,因此非托管资源的生命周期不由GC管理,如果不正确释放,可能会导致资源泄漏或非预期事件发生。

实现IDisposable接口

当你的类使用了一些非托管资源时,应该实现IDisposable接口,以确保这些资源能够被正确释放。IDisposable接口要求实现一个Dispose方法,该方法用于释放资源。通常,Dispose方法会有两个版本:

  • 一个公共的Dispose方法,用于释放托管和非托管资源。
  • 一个受保护的Dispose(bool disposing)方法,用于区分托管资源和非托管资源的释放。

Dispose(bool disposing)方法中:

  • disposingtrue时,释放托管资源。
  • disposingfalse时(通常在析构函数中调用),只释放非托管资源。

示例

public class ResourceHolder : IDisposable
{
    // 用于标记资源是否已经被释放
    private bool _disposed = false;

    // 假设这是一个非托管资源
    private IntPtr _unmanagedResource;

    public void UseResource()
    {
        if (!_disposed)
        {
            // 使用资源
        }
        else
        {
            throw new ObjectDisposedException("ResourceHolder");
        }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                // 释放托管资源
            }

            // 释放非托管资源
            if (_unmanagedResource != IntPtr.Zero)
            {
                // 假设的释放非托管资源的代码
                // NativeMethods.ReleaseResource(_unmanagedResource);
                _unmanagedResource = IntPtr.Zero;
            }

            _disposed = true;
        }
    }

    ~ResourceHolder()
    {
        // 确保资源被释放
        Dispose(false);
    }
}

// 使用示例
class Program
{
    static void Main()
    {
        using (ResourceHolder resource = new ResourceHolder())
        {
            resource.UseResource();
            // 其他代码...
        }

        // 此时ResourceHolder的Dispose方法会被自动调用
    }
}

ResourceHolder类管理了一个非托管资源(假设为一个指针)。Dispose方法确保了资源被正确释放,而析构函数确保了即使没有显式调用Dispose方法,资源也不会泄漏。

_disposed字段用于跟踪资源是否已经被释放,以防止多次释放资源。

GC.SuppressFinalize(this)调用告诉垃圾回收器不需要为当前对象调用析构函数,因为资源已经被显式释放。

using语句确保了Dispose方法在MyResource对象不再需要时被调用,这是管理资源释放的一种简洁且安全的方式。

标签:释放,C#,托管,Dispose,回收,GC,ResourceHolder,资源
From: https://www.cnblogs.com/lyh523329053/p/18213655

相关文章

  • Service
    启动和停止classMainActivity:AppCompatActivity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)startServiceBtn.setOnClickListener{......
  • 【Spring】Scope注解的使用以及原理
    1 前言Spring帮助我们管理着Bean,那么带来的一个思考就是Bean该维护一个实例呢?还是每次都获取新的呢?单例的依赖多例的作用范围的变化怎么处理呢?也就是Bean的一个作用范围的管理是怎么控制的呢?这就是我们本节要看的Scope。2 Scope介绍2.1 @Scope注解在spring中,......
  • BUUCTF-WEB(36-40)
    [BSidesCF2020]Hadabadday参考:[BUUCTF:BSidesCF2020]Hadabadday_末初的技术博客_51CTO博客[buuctf-BSidesCF2020]Hadabadday(小宇特详解)-CSDN博客应该是文件包含我这里使用;1,然后报错,我发现他是直接会加上一个.php,那我们试试伪协议读取?category=php://filter/......
  • C# 混淆加密大师1.1.0更新, 新增资源文件加密, 防虚拟机, 异步混淆等新功能
    C#混淆加密大师是一款强大的工具,专为保护C#开发的dll和exe文件而设计,适用于各种应用程序,包括Winform、WPF、Unity游戏以及控制台程序。它支持从.NetFramework2.0到.NetFramework4.x,以及.NETCore2.0直至最新的.NET8版本。C#混淆加密大师不仅提供代码加密混淆功能,还能对EXE文......
  • ASP.NET CORE kindeditor在线编辑器示例(上传多图和插入VIDEO标签)
    2024年05月26日更新以前记录都过时了,ASP.NETASPX版本的直接看他里面的示例就好,今天把自己弄的上传多图和插入video标签的代码贴上来。。以备以后需要用的时候直接复制粘贴。。。ASP.NETCORE版本,VS2022,原来里面也有个上传多图和插入视频的。。用的flash来上传多图和插入的embe......
  • JavaScript 系列教程 III JavaScript 代码质量
    ......
  • C和C++内存管理
    C和C++的内存管理C/C++中程序内存区域的划分C语言中动态内存管理方式C++中动态内存管理方式new和delete操作内置类型new和delete操作自定义类型operratornew函数和operatordelete函数new和delete的实现原理内置类型自定义类型new的原理delete的原理newT[N]的原理dele......
  • centos7安装postgresql-15
    摘要:本文将提供一个详细的教程,介绍如何在CentOS7操作系统上安装最新版本的PostgreSQL15。您将学习到如何添加PostgreSQL官方软件仓库,并使用yum命令进行安装和配置。1.引言PostgreSQL是一个功能强大的开源关系型数据库管理系统,被广泛用于企业级应用和数据存储。安装最新版......
  • CCF-GESP 等级考试 2024年3月认证C++一级真题解析
    2024年03月真题1单选题第1题C++表达式(3-2)*3+5的值是()。A.-13B.8C.2D.0正确答案:B.8解析:首先计算括号中的表达式(3-2),得到(1)。接下来进行乘法运算(1*3),得到(3)。最后进行加法运算(3+5),得到(8)。因此,表达式的值是(8)。第2题C++......
  • CCF-GESP 等级考试 2024年3月认证C++一级真题
    2024年03月真题1单选题第1题C++表达式(3-2)*3+5的值是()。A.-13B.8C.2D.0第2题C++语句cout<<"5%2="<<5%2执行后的输出是()。A.22B.11C.5%2=2D.5%2=1第3题执行C++语句cin>>a时如果输入5+2,下述说法正确的是()。A.变量a将被......