IDisposable 模式,SafeFileHandle 是非托管资源吗?
IDisposable pattern, is SafeFileHandle an unmanaged resource?
采用 Resharper 生成的 IDisposable
模式的以下片段:
[NotNull]
private SafeFileHandle Handle { get; }
#region IDisposable
private bool IsDisposed { get; set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void ReleaseUnmanagedResources()
{
// TODO release unmanaged resources here
}
private void Dispose(bool disposing)
{
if (IsDisposed)
return;
ReleaseUnmanagedResources();
if (disposing)
Handle.Dispose();
IsDisposed = true;
}
~Whatever()
{
Dispose(false);
}
Resharper 将 SafeFileHandle
视为托管资源,但此句柄是关于非托管资源 (CreateFile
)。
问题:
在处理 SafeFileHandle
时,应该将其视为托管资源还是非托管资源?
所有 C# 类 和结构都是托管资源1.
非托管资源通常由 IntPtr
或类似内容指向。您通常需要做一些非常慎重的事情才能得到一个(例如 P/Invoking 一些本机方法,或者使用 Marshal
上的其中一种方法)。
SafeFileHandle
是SafeHandle
的子类,是专门用来包装非托管资源的类型。 SafeHandle
定义自己的终结器,必要时以合适的方式释放非托管资源。
建议 永远不要 拥有自己的非托管资源,而是 总是 使用 SafeHandle
/ CriticalFinalizerObject
子类来管理它们。
这避免了 P/Invoke 大陷阱之一,也意味着您不必在代码中实现完整的 IDisposable
模式:您只需要定义一个 Dispose()
方法,它在您的 SafeHandles
上调用 Dispose()
,并且不需要实现终结器。
(有些人可能出于性能原因需要偏离这一点,但这样的人少之又少)
1具有 unmanaged
约束的通用类型...
采用 Resharper 生成的 IDisposable
模式的以下片段:
[NotNull]
private SafeFileHandle Handle { get; }
#region IDisposable
private bool IsDisposed { get; set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void ReleaseUnmanagedResources()
{
// TODO release unmanaged resources here
}
private void Dispose(bool disposing)
{
if (IsDisposed)
return;
ReleaseUnmanagedResources();
if (disposing)
Handle.Dispose();
IsDisposed = true;
}
~Whatever()
{
Dispose(false);
}
Resharper 将 SafeFileHandle
视为托管资源,但此句柄是关于非托管资源 (CreateFile
)。
问题:
在处理 SafeFileHandle
时,应该将其视为托管资源还是非托管资源?
所有 C# 类 和结构都是托管资源1.
非托管资源通常由 IntPtr
或类似内容指向。您通常需要做一些非常慎重的事情才能得到一个(例如 P/Invoking 一些本机方法,或者使用 Marshal
上的其中一种方法)。
SafeFileHandle
是SafeHandle
的子类,是专门用来包装非托管资源的类型。 SafeHandle
定义自己的终结器,必要时以合适的方式释放非托管资源。
建议 永远不要 拥有自己的非托管资源,而是 总是 使用 SafeHandle
/ CriticalFinalizerObject
子类来管理它们。
这避免了 P/Invoke 大陷阱之一,也意味着您不必在代码中实现完整的 IDisposable
模式:您只需要定义一个 Dispose()
方法,它在您的 SafeHandles
上调用 Dispose()
,并且不需要实现终结器。
(有些人可能出于性能原因需要偏离这一点,但这样的人少之又少)
1具有 unmanaged
约束的通用类型...