打电话不安全吗:
组件.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 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
编写方法时并没有考虑到这种类型的安全性,因为它们只期望在对象最终确定之前被调用。
在您想要考虑做一些聪明的事情(例如在终结器中触摸其他对象)之前,请阅读克里斯·布鲁姆的博客 http://blogs.msdn.com/b/cbrumme/有关该主题的帖子;这是一个很好的起点 http://blogs.msdn.com/b/cbrumme/archive/2004/02/20/77460.aspx.
一般来说,除非在非常特殊的情况下,并且您知道Dispose
即使在完成后调用时,所包含对象的方法也会按预期运行,我假设您询问的模式不安全,并且会坚持使用推荐的传递模式bool disposing
参数,并且仅接触托管对象(如果是)true
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)