【发布时间】:2013-04-30 09:49:42
【问题描述】:
考虑以下我最近更改为使用FileStream.SafeFileHandle 的代码:
public static void FastWrite<T>(FileStream fs, T[] array, int offset, int count) where T: struct
{
int sizeOfT = Marshal.SizeOf(typeof(T));
GCHandle gcHandle = GCHandle.Alloc(array, GCHandleType.Pinned);
try
{
uint bytesWritten;
uint bytesToWrite = (uint)(count * sizeOfT);
var overlapped = new NativeOverlapped();
if
(
!WriteFile
(
fs.SafeFileHandle,
new IntPtr(gcHandle.AddrOfPinnedObject().ToInt64() + (offset*sizeOfT)),
bytesToWrite,
out bytesWritten,
ref overlapped
)
)
{
throw new IOException("Unable to write file.", new Win32Exception(Marshal.GetLastWin32Error()));
}
Debug.Assert(bytesWritten == bytesToWrite);
GC.KeepAlive(fs); // <--- Is this really not necessary?
}
finally
{
gcHandle.Free();
}
}
[DllImport("kernel32.dll", SetLastError=true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WriteFile
(
SafeFileHandle hFile,
IntPtr lpBuffer,
uint nNumberOfBytesToWrite,
out uint lpNumberOfBytesWritten,
ref NativeOverlapped lpOverlapped
);
我之前添加了 GC.KeepAlive(fs) 以确保在 Windows API WriteFile() 调用返回之前不会对 FileStream 进行垃圾收集。
但是,在更改为使用 SafeFileHandle 之后,代码分析现在告诉我,warning CA2004: Remove calls to GC.KeepAlive 没有必要:
如果您要转换为 SafeHandle 用法,请删除对 GC.KeepAlive(对象)的所有调用。
我已经查阅了FileStream.SafeFileHandle 上的文档,但我不清楚删除对GC.KeepAlive() 的调用是否真的安全。
删除它绝对安全吗?我是否正确使用它?
另外,任何人都可以指出一些关于使用 SafeHandle 的体面文档吗?
【问题讨论】:
-
@Damien_The_Unbeliever 呵呵,感谢您的编辑。它也在标题中!
标签: c# filestream safehandle