Microsoft C#编码规范 下载本文

Page 45

?一定不要锁定短暂存在的对象。锁定短暂存在的对象会延长在P/Invoke调用时内存缓冲区的生存期。锁定会阻止垃圾回收器重新分配托管堆内对象内存,或者是托管委托的地址。然而,锁定长期存在的对象是可以接受的,因为其是在应用程序初始化期间创建的,相较于短暂存在对象,它们并不会被移动。长期锁定短暂存在的对象代价非常高昂,因为内存压缩经常发生在第0代的垃圾回收时,垃圾回收器不能重新分配被锁定的对象。这样会造成低效的内存管理,极大的降低性能表现。更多复制和锁定请参考http://msdn.microsoft.com/en-us/library/23acw07k.aspx。

?一定请在P/Invoke签名中将CharSet设为CharSet.Auto,SetLastError设为true。举例,

// C# sample:

[DllImport(\, CharSet = CharSet.Auto, SetLastError = true)] publicstaticexternSafeFileMappingHandle OpenFileMapping(

FileMapAccess dwDesiredAccess, bool bInheritHandle, string lpName);

?您应该将非托管资源封装进SafeHandle类。SafeHandle类已经在可终结类型章节中进行了讨论。比如,文件映射句柄被封装成如下代码:

///

/// Represents a wrapper class for a file mapping handle. ///

[SuppressUnmanagedCodeSecurity,

HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]

internalsealedclassSafeFileMappingHandle : SafeHandleZeroOrMinusOneIsInvalid {

[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] private SafeFileMappingHandle() : base(true) { }

[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)] public SafeFileMappingHandle(IntPtr handle, bool ownsHandle) : base(ownsHandle) {

base.SetHandle(handle); }

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success),

? 2016 Microsoft Corporation. All rights reserved.

Page 46

DllImport(\, CharSet = CharSet.Auto, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]

privatestaticexternbool CloseHandle(IntPtr handle);

protectedoverridebool ReleaseHandle() {

return CloseHandle(base.handle); } }

?您应该在调用会设置Win32最后错误代码的 P/Invoked 函数失败时,抛出Win32Exception 异常。如果函数使用了非托管资源,请在finally块内释放资源。

// C# sample:

SafeFileMappingHandle hMapFile = null; try {

// Try to open the named file mapping.

hMapFile = NativeMethod.OpenFileMapping( FileMapAccess.FILE_MAP_READ, // Read access

false, // Do not inherit the name FULL_MAP_NAME // File mapping name );

if(hMapFile.IsInvalid) {

thrownewWin32Exception(); }

... } finally {

if(hMapFile != null) {

// Close the file mapping object. hMapFile.Close(); hMapFile = null; } }

? 2016 Microsoft Corporation. All rights reserved.