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

更新:2007 年 11 月

TypeName

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);
        }
    }
}

相关规则

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

正确调用 GC.SuppressFinalize

可释放类型应声明终结器

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

请参见

参考

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

其他资源

清理非托管资源