Share via


CA1049:拥有本机资源的类型应是可释放的

类型名

TypesThatOwnNativeResourcesShouldBeDisposable

CheckId

CA1049

类别

Microsoft.Design

是否重大更改

非重大更改

原因

某类型引用了 System.IntPtr 字段、System.UIntPtr 字段或 System.Runtime.InteropServices.HandleRef 字段,但无法实现 System.IDisposable

规则说明

该规则假定 IntPtrUIntPtrHandleRef 字段存储指向非托管资源的指针。 分配非托管资源的类型应该实现 IDisposable,以使调用方可以根据需要释放这些资源,并缩短持有这些资源的对象的生存期。

清理非托管资源的建议设计模式是分别使用 Object.Finalize 方法和 IDisposable.Dispose 方法,以隐式和显式方式释放这些资源。 在确定某个对象已不可访问之后,垃圾回收器将在某个不确定的时间调用该对象的 Finalize 方法。 在调用 Finalize 之后,需要执行附加垃圾回收操作以释放该对象。 使用 Dispose 方法,调用方可以根据需要在垃圾回收器释放资源之前显式释放这些资源。 在清理非托管资源后,Dispose 必须调用 GC.SuppressFinalize 方法以通知垃圾回收器不再需要调用 Finalize;这样可以消除附加的垃圾回收操作,缩短对象的生存期。

如何解决冲突

要修复与该规则的冲突,请实现 IDisposable

何时禁止显示警告

如果类型没有引用非托管资源,则可以安全地禁止显示此规则发出的警告。 否则,不要禁止显示此规则发出的警告,因为如果无法实现 IDisposable,可能会导致非托管资源不可用或被占用。

示例

下面的示例演示一个实现 IDisposable 来清理非托管资源的类型。

Imports System

Namespace DesignLibrary

    Public Class UnmanagedResources
        Implements IDisposable

       Dim unmanagedResource As IntPtr
       Dim disposed As Boolean = False

       Sub New 
           ' Allocate the unmanaged resource ...
       End Sub

       Overloads Sub Dispose() Implements IDisposable.Dispose
           Dispose(True)
           GC.SuppressFinalize(Me)
       End Sub

       Protected Overloads Overridable Sub Dispose(disposing As Boolean)
           If Not(disposed) Then

               If(disposing) Then
                   ' Release managed resources.
               End If

               ' Free the unmanaged resource ...

               unmanagedResource = IntPtr.Zero

               disposed = True

           End If
       End Sub

       Protected Overrides Sub Finalize()
           Dispose(False)
       End Sub

    End Class

End Namespace
using System;

namespace DesignLibrary
{
    public class UnmanagedResources : IDisposable
    {
        IntPtr unmanagedResource;
        bool disposed = false;

        public UnmanagedResources() 
        {
            // Allocate the unmanaged resource ...
        }

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

        protected virtual void Dispose(bool disposing)
        {
            if(!disposed)
            {
                if(disposing)
                {
                    // Release managed resources.
                }

                // Free the unmanaged resource ...

                unmanagedResource = IntPtr.Zero;

                disposed = true;
            }
        }

        ~UnmanagedResources()
        {
            Dispose(false);
        }
    }
}

相关规则

CA2115:使用本机资源时调用 GC.KeepAlive

CA1816:正确调用 GC.SuppressFinalize

CA2216:可释放类型应声明终结器

CA1001:具有可释放字段的类型应该是可释放的

请参见

参考

实现 Finalize 和 Dispose 以清理非托管资源

其他资源

清理非托管资源