.NET中的SafeBuffer和SafeHandleZeroOrMinusOneIsInvalid之间的主要区别是什么?

时间:2013-11-14 09:41:24

标签: c# .net c++-cli

主要区别在哪里?我知道SafeBuffer派生出SafeHandleZeroOrMinusOneIsInvalid但还有什么?

我应该何时使用其中一种?

我需要分配和控制本机阵列(在CPU或GPU上)。我的托管自定义数组应该实现SafeBuffer还是SafeHandleZeroOrMinusOneIsInvalid? SafeBuffer作为名称听起来更合理,但为什么我应该实现它并且必须在使用它之前调用Initialize?

1 个答案:

答案 0 :(得分:3)

  

主要区别在哪里?

无处不在,他们没有任何共同之处。 SaveBuffer继承自SafeHandle,以利用SafeHandle提供的关键终结器。即使在最严峻的情况下也会释放缓冲区,例如程序中的硬崩溃通常会阻止终结器执行。

SaveBuffer是操作系统调用获取的非托管内存的包装器。它具有完全一个方法,它仍然是抽象的,即ReleaseHandle()方法。由于不同的winapi调用有不同的方式来释放与内存相关联的句柄。例如,LocalAlloc()需要LocalFree()。 SysAllocString()需要SysFreeString()。 MapViewOfFile()需要UnmapViewOfFile()等等。

您可以从SaveBuffer()派生自己的类,以利用安全句柄保证。它需要一个构造函数,它接受非托管指针并调用SetHandle()。它需要实现ReleaseHandle()以再次释放内存。

你是否真的应该这样做非常值得怀疑。 ReleaseHandle()方法由关键终结器调用。在这种方法中你无法做很多事情,对关键终结器的要求很高,以确保终结器本身确实会导致任何阻止其他关键终结器运行的损坏。例如,CLR以防止生成异常的模式运行。只有在自定义CLR托管环境中才能确保正常运行时间,SQL Server才是主要的例子。如果你进行操作系统调用就可以使用它,这是一个坚如磐石的代码。一个GPU缓冲区,嗯,不是那么多。只需使用自己的终结器创建自己的包装器,您就可能领先一步。当释放调用失败时,您将有更多 更容易调试意外事件。