gpt4 book ai didi

c# - 从 Finalizer 调用托管资源安全吗? (如果我检查为空)

转载 作者:行者123 更新时间:2023-11-30 15:03:34 25 4
gpt4 key购买 nike

调用是否不安全:

组件.Dispose(); (如果我检查为空)

如果我将代码更改为这样,则来自终结器:

~MyResource()
{
Dispose();
}
public void Dispose()
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
if(component != null) component.Dispose(); // !!! //

CloseHandle(handle);
handle = IntPtr.Zero;

disposed = true;

}
GC.SuppressFinalize(this);
}

我知道这行得通 - 但它安全吗?

(来自下面的例子?)

代码示例:(修改代码前)

http://msdn.microsoft.com/en-us/library/system.idisposable.dispose.aspx

using System;
using System.ComponentModel;

// The following example demonstrates how to create
// a resource class that implements the IDisposable interface
// and the IDisposable.Dispose method.

public class DisposeExample
{
// A base class that implements IDisposable.
// By implementing IDisposable, you are announcing that
// instances of this type allocate scarce resources.
public class MyResource: IDisposable
{
// Pointer to an external unmanaged resource.
private IntPtr handle;
// Other managed resource this class uses.
private Component component = new Component();
// Track whether Dispose has been called.
private bool disposed = false;

// The class constructor.
public MyResource(IntPtr handle)
{
this.handle = handle;
}

// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}

// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!this.disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
component.Dispose();
}

// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
CloseHandle(handle);
handle = IntPtr.Zero;

// Note disposing has been done.
disposed = true;

}
}

// Use interop to call the method necessary
// to clean up the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);

// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~MyResource()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
}
public static void Main()
{
// Insert code here to create
// and use the MyResource object.
}
}

最佳答案

如果不知道“组件”的实现细节,很难确定这样做是否安全。对象的终结是无序的,并且不遵循包含层次结构,因此虽然“组件”实例可能不是 null,但在您调用 Dispose 时它可能已经完成在上面。通常 Dispose 方法在编写时并没有考虑到这种类型的安全性,因为它们只希望在对象完成之前被调用。

在你甚至想要考虑做一些聪明的事情之前,比如在终结器中触摸其他对象,请阅读 Chris Brumme's blog关于该主题的帖子; this one is a good starting point .

通常,除非在非常特殊的情况下,并且您知道所包含对象的 Dispose 方法即使在已完成时调用也会按预期行为,我假设您所问的模式about 是不安全的,并且会坚持传递 bool disposing 参数的推荐模式,并且仅在它为 true 时才接触托管对象。

关于c# - 从 Finalizer 调用托管资源安全吗? (如果我检查为空),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11363706/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com