Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 直接包含非托管资源,在.NET2.0+中,这些资源应包装在SafeHandle中_C#_Dispose - Fatal编程技术网

C# 直接包含非托管资源,在.NET2.0+中,这些资源应包装在SafeHandle中

C# 直接包含非托管资源,在.NET2.0+中,这些资源应包装在SafeHandle中,c#,dispose,C#,Dispose,我认为Dispose(true)将释放托管和非托管资源,因为我们不需要再次调用finalize,这就是为什么我们在Dispose(true)之后编写GC.supersfinalize() 我们在析构函数中调用Dispose(false),以释放非托管资源,并将由运行时而不是用户代码调用。良好链接。处置模式是处理托管资源必须知道的。@ RigelMelt:我认为它是一种反模式。一个类应该处理托管资源、一个非托管资源或一组紧密耦合的非托管资源。处理任何托管资源的类不应处理任何非托管资源。由于其子代将

我认为
Dispose(true)
将释放托管和非托管资源,因为我们不需要再次调用finalize,这就是为什么我们在
Dispose(true)
之后编写
GC.supersfinalize()


我们在析构函数中调用
Dispose(false)
,以释放非托管资源,并将由运行时而不是用户代码调用。

良好链接。处置模式是处理托管资源必须知道的。@ RigelMelt:我认为它是一种反模式。一个类应该处理托管资源、一个非托管资源或一组紧密耦合的非托管资源。处理任何托管资源的类不应处理任何非托管资源。由于其子代将处理托管资源,因此其子代也不应处理非托管资源。当后代类不应该添加终结器时,为什么还要添加终结器呢?我看不出这个问题。如果缓存需要释放的对象,那么类应该实现dispose,以便能够清理对象。如果类处理非托管资源,那么它应该实现一个终结器。如果它实现了终结器,则实现dispose模式。我不明白你所描述的是如何改变这种情况的。好吧,这一定是个骗局:你读过这本书吗?它深入讨论了dispose模式。因此,如果我试图清理我的类拥有的一堆
位图
对象(通过在我的类的dispose方法中处理它们),我应该以任何方式清理它们,还是仅在从dispose调用它时清理(true)?如果它是支持IDisposable的托管对象,那么是的,我们在dispose中进行清理(true). 您不必担心位图是否保留在非托管资源上,尤其是当位图类遵循上述模式时。对。位图类有自己的终结器,就您的类而言,它只是一个需要处理的托管对象。当
Dispose(false)
在某个对象
George
上运行时,可能已经清理了
George
引用的任何
IDisposable
对象,将在没有George帮助的情况下进行清理、仍在使用或无法从终结器线程安全清理。因此,在大多数情况下,
Dispose(false)
没有任何作用;在析构函数中没有任何作用的类不应该有析构函数。在您提供的链接中,何时调用Dispose(false)。我看不到有人提到它。(似乎Dispose(true)是唯一被调用的东西…)是否有某种约定会被调用Dispose(false)?您应该只在终结器中传递
false
。Dispose方法应始终通过
true
。库马尔链接中的例子很好地说明了这一点。终结器仅由垃圾收集器运行,因此在这种情况下,您只希望处置非托管资源。如果您自己调用Dispose,那么您希望处置托管和非托管资源。因此,MSDN示例没有添加这样的方法:
~DisposableResource{Dispose(false);}
对吗?啊,我现在明白了!如果我的类有一些真正非托管的资源,那么它将需要带有dispose调用的析构函数。由于我使用的所有“非托管”资源都包装在托管类中,因此无论如何,它们都将在GC时清理。无需特殊清理。是和否。您仍应在处理完的对象上调用Dispose。您可以在问题中发布的示例中使用调用Dispose(true)的Dispose方法。这将使具有您的类实例的其他类能够在其自身之后进行清理。在您提供的第二个链接中,何时调用Dispose(false)?我看不到有人提到它。(似乎Dispose(true)是唯一被调用的东西…)是否有一些约定会被调用Dispose(false)?如果没有,那么拥有这两个方法签名有什么意义呢?它会在类的终结器(C#析构函数)或任何带有终结器的继承类中调用。请参阅第一个链接:))这里有一个调用Dispose(false)的示例。@Vaccano:永远不要使用参数值false调用它(如果类的派生版本需要添加非托管资源,则该资源应封装到其他类中,然后作为托管资源使用)。微软在生产.NET2.0时认识到了将托管资源和非托管资源结合起来的问题;他们继续推行这种Dispose模式似乎很愚蠢;如果您自己的代码(通常是终结器/析构函数)执行此操作,或者如果其他人从您的类派生并错误地添加了调用Dispose(false)的终结器/析构函数,则将使用参数值false调用Dispose。我不知道在任何情况下,从对象以外的任何对象派生的类都应该添加调用Dispose(false)的析构函数/终结器;我可以理解使用受保护的可重写Dispose方法与不可重写的公共Dispose方法不同的一些优点,但是……我认为Disposing参数没有任何用处,只是为了确保任何派生类终结器都不会破坏任何东西。
~OwnerDrawnPanel()
{
    _font.Dispose();
}
public void Dispose()
private void Dispose(bool)