主要区别在哪里?我知道 SafeBuffer 派生 SafeHandleZeroOrMinusOneIsInvalid 但还有什么?
我什么时候应该使用其中一种?
我需要分配和控制本机数组(在 CPU 或 GPU 上)。我的托管自定义数组应该实现 SafeBuffer 还是 SafeHandleZeroOrMinusOneIsInvalid?SafeBuffer 作为一个名字听起来更合理,但我为什么要实现它并且必须在使用它之前调用 Initialize 呢?
主要区别在哪里?
在任何地方,他们都没有共同点。SaveBuffer 继承自 SafeHandle 以利用 SafeHandle 提供的关键终结器。这确保即使在最可怕的情况下也会释放缓冲区,例如程序中的硬崩溃通常会阻止终结器执行。
SaveBuffer 是由操作系统调用获得的非托管内存的包装器。它只有一个仍然是抽象的方法,ReleaseHandle() 方法。由于不同的 winapi 调用有不同的方式来释放与内存关联的句柄。例如,LocalAlloc() 需要 LocalFree()。SysAllocString() 需要 SysFreeString()。MapViewOfFile() 需要 UnmapViewOfFile() 等。
您可以从 SaveBuffer() 派生自己的类以利用安全句柄保证。它需要一个构造函数来获取非托管指针并调用 SetHandle()。并且需要执行 ReleaseHandle() 来再次释放内存。
你是否真的应该这样做是非常值得怀疑的。ReleaseHandle() 方法由关键终结器调用。在这种方法中你不能做很多事情,对关键终结器的要求非常高,以确保终结器本身确实会导致任何会阻止其他关键终结器运行的损坏。例如,CLR 以防止生成异常的模式运行。只有在为正常运行时间提供强有力保证的自定义 CLR 托管环境中才真正重要,SQL Server 是主要示例。如果您进行操作系统调用,则可以使用它,即坚固如磐石的代码。GPU 缓冲区,嗯,没那么多。通过使用自己的终结器创建自己的包装器,您可能会领先。你'当发布调用失败时,更容易调试事故。