/******************************************************************************
Module: OSHandle.cs
Notices: Copyright (c) 2002 Jeffrey Richter
******************************************************************************/
using System;
///////////////////////////////////////////////////////////////////////////////
// Implementing the IDisposable interface signals users of
// this class that it offers the dispose pattern.
public sealed class OSHandle : IDisposable { // This field holds the Win32 handle of the unmanaged resource.
private IntPtr handle; // This constructor initializes the handle.
public OSHandle(IntPtr handle) {
this.handle = handle;
} // When garbage collected, this Finalize method, which
// will close the unmanaged resource's handle, is called.
~OSHandle() {
Dispose(false);
} // This public method can be called to deterministically
// close the unmanaged resource's handle.
public void Dispose() {
// Because the object is explicitly cleaned up, stop the
// garbage collector from calling the Finalize method.
GC.SuppressFinalize(this); // Call the method that actually does the cleanup.
Dispose(true);
} // This public method can be called instead of Dispose.
public void Close() {
Dispose();
} // The common method that does the actual cleanup.
// Finalize, Dispose, and Close call this method.
// Because this class is sealed, this method is private.
// If this class weren't sealed, this method wouldn抰 be protected.
private void Dispose(Boolean disposing) {
// Synchronize threads calling Dispose/Close simultaneously.
lock (this) {
if (disposing) {
// The object is being explicitly disposed of/closed, not
// finalized. It is therefore safe for code in this if
// statement to access fields that reference other
// objects because the Finalize method of these other objects
// hasn抰 yet been called.
// For the OSHandle class, there is nothing to do in here.
} // The object is being disposed of/closed or finalized.
if (IsValid) {
// If the handle is valid, close the unmanaged resource.
// NOTE: Replace CloseHandle with whatever function is
// necessary to close/free your unmanaged resource.
CloseHandle(handle); // Set the handle field to some sentinel value. This precaution
// prevents the possibility of calling CloseHandle twice.
handle = InvalidHandle;
}
}
} // Public property to return the value of an invalid handle.
// NOTE: Make this property return an invalid value for
// whatever unmanaged resource you're using.
public IntPtr InvalidHandle {
get { return IntPtr.Zero; }
} // Public method to return the value of the wrapped handle
public IntPtr ToHandle() {
if (IsInvalid)
throw new ObjectDisposedException("The handle was closed.");
return handle;
} // Public implicit cast operator returns the value of the wrapped handle
public static implicit operator IntPtr(OSHandle osHandle) {
return osHandle.ToHandle();
} // Public properties to return whether the wrapped handle is valid.
public Boolean IsValid {
get { return (handle != InvalidHandle); }
} public Boolean IsInvalid {
get { return !IsValid; }
} // Private method called to free the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
}
//////////////////////////////// End of File //////////////////////////////////
Module: OSHandle.cs
Notices: Copyright (c) 2002 Jeffrey Richter
******************************************************************************/
using System;
///////////////////////////////////////////////////////////////////////////////
// Implementing the IDisposable interface signals users of
// this class that it offers the dispose pattern.
public sealed class OSHandle : IDisposable { // This field holds the Win32 handle of the unmanaged resource.
private IntPtr handle; // This constructor initializes the handle.
public OSHandle(IntPtr handle) {
this.handle = handle;
} // When garbage collected, this Finalize method, which
// will close the unmanaged resource's handle, is called.
~OSHandle() {
Dispose(false);
} // This public method can be called to deterministically
// close the unmanaged resource's handle.
public void Dispose() {
// Because the object is explicitly cleaned up, stop the
// garbage collector from calling the Finalize method.
GC.SuppressFinalize(this); // Call the method that actually does the cleanup.
Dispose(true);
} // This public method can be called instead of Dispose.
public void Close() {
Dispose();
} // The common method that does the actual cleanup.
// Finalize, Dispose, and Close call this method.
// Because this class is sealed, this method is private.
// If this class weren't sealed, this method wouldn抰 be protected.
private void Dispose(Boolean disposing) {
// Synchronize threads calling Dispose/Close simultaneously.
lock (this) {
if (disposing) {
// The object is being explicitly disposed of/closed, not
// finalized. It is therefore safe for code in this if
// statement to access fields that reference other
// objects because the Finalize method of these other objects
// hasn抰 yet been called.
// For the OSHandle class, there is nothing to do in here.
} // The object is being disposed of/closed or finalized.
if (IsValid) {
// If the handle is valid, close the unmanaged resource.
// NOTE: Replace CloseHandle with whatever function is
// necessary to close/free your unmanaged resource.
CloseHandle(handle); // Set the handle field to some sentinel value. This precaution
// prevents the possibility of calling CloseHandle twice.
handle = InvalidHandle;
}
}
} // Public property to return the value of an invalid handle.
// NOTE: Make this property return an invalid value for
// whatever unmanaged resource you're using.
public IntPtr InvalidHandle {
get { return IntPtr.Zero; }
} // Public method to return the value of the wrapped handle
public IntPtr ToHandle() {
if (IsInvalid)
throw new ObjectDisposedException("The handle was closed.");
return handle;
} // Public implicit cast operator returns the value of the wrapped handle
public static implicit operator IntPtr(OSHandle osHandle) {
return osHandle.ToHandle();
} // Public properties to return whether the wrapped handle is valid.
public Boolean IsValid {
get { return (handle != InvalidHandle); }
} public Boolean IsInvalid {
get { return !IsValid; }
} // Private method called to free the unmanaged resource.
[System.Runtime.InteropServices.DllImport("Kernel32")]
private extern static Boolean CloseHandle(IntPtr handle);
}
//////////////////////////////// End of File //////////////////////////////////
接口是用来区分一个object 能做什么(can do ), 而继承是用来说明一个object是什么(is a )Dispose用在垃圾回收器和手动释放资源时。如果你又资源要手动释放,直接调用即可。如果忘记了,也没有关系,gc会在施放对象的时候同样释放一次。
用IDisposable接口释放.NET资源
--------------------------------------------------------------------------------
使用Dispose 模式能够适当地释放资源,但会增加系统开销。
by Mickey Williams
通过使用Dispose模式可以适当地释放非内存资源,比如数据库连接、Win32 interop组件和操作系统的句柄。你不要指望垃圾收集器能够立即将资源释放掉,因为垃圾收集器是由于管制堆(Managed Heap)的内存紧张时才触发的。你可以快速消耗掉例如数据库连接等少量资源,但会给程序的扩展性造成副面影响。在不必要的时候不能实现Dispose模式,因为它可能会增加系统开销,而这在很多情况下是可以避免的。在.NET当中Dispose 模式是由一个IDisposable接口来实现的,它包括一个简单的方法--Dispose:interface IDisposable
{
void Dispose();
}
最明显的例子是在一个类里当类的实例抢占住一个非管制资源(unmanaged resource)时必须实现IDisposable,比如一个本地数据连接或是操作系统的句柄。另外,记下一个经常被忽略的应该实现IDisposable接口的例子。当一个类实现IDisposable时,实例的正确用法是当对象不在需要时调用Dispose方法删除它,因此,在你实现一个类,而该类又包含其他实现IDisposable的类时,必须调用Dispose方法。这通常意味着在该类中你必须实现IDisposable,即使它无法直接处理非管制资源。以下是一个实现IDisposable接口的典型模式:public class SlalomRacer: IDisposable
{
bool _disposed = false; public bool IsDisposed
{
get { return _disposed; }
set { _disposed = value; }
} ~SlalomRacer()
{
InternalDispose(false);
} public void Dispose()
{
InternalDispose(true);
} protected void InternalDispose(bool disposing)
{
if(disposing)
{
GC.SuppressFinalize(this);
_managedThing.Dispose();
}
_unmanagedThing.Dispose();
}
[...]
} 在前面的代码片断中,当IDisposable被实现时,可以通过两种方法调用disposal代码。首先,如果你直接调用Dispose方法,所有管制和非管制对象均会被列为被清除目标。可以看到终止操作会执行一个阻止对象被清除掉的优化的步骤。还注意到可以安全地多次调用Dispose方法。调用dispose方法之后,会使用一个标志来确保这个对象上的任何一个方法都不能被调用,示例代码如下:public void SeekHotTub()
{
if(IsDisposed)
throw new ObjectDisposedException("BT");
}
ObjectDisposedException会提醒你前面已经使用了一个disposed对象。在一个使用过disposed对象上调用其他方法时引发异常是完全有必要的--毕竟,你不能再次使用这些disposed对象。其次,如果你不调用这个Dispose方法,终止操作会自己调用Dispose(false),它会采用一个和前段代码稍有不同的代码路径。第一,不清除那些管制对象,即使他们也实现了IDisposable接口。你无法确定对象引用是有效的--这些对象可能在等待操作的终止,或者已经被终止了。第二,也没有必要去调用GC.SuppressFinalization,因为这些对象已被终止使用了。最后,如果你在使用C#,你应该利用其语言固有的对IDisposable接口的支持来实现对象清除,你可以使用以下声明:using(SlalomRacer mickey = new SlalomRacer())
{
// use mickey here
mickey.RunGates();
mickey.GetStitches();
}
// mickey disposed automatically here
C#编辑器会适当地发出调用Dispose方法的IL代码,即使会引发异常。
在你的例子中,OK实现了IDisposable接口,表明所有别的类可以通过IDisposable接口操作你的对象,也就是说可以通过IDisposable接口去释放资源。而我们在实现接口的时候,需要满足接口的规范要求,实现接口行为。
现在部署的任何COM 组件都可以在接口转换中使用。通常情况下,所需的调整是完全自动进行的。
特别是,可以使用运行时可调用包装 (RCW) 从 .NET 框架访问 COM 组件。此包装将 COM 组件提供的 COM 接口转换为与 .NET 框架兼容的接口。对于 OLE 自动化接口,RCW 可以从类型库中自动生成;对于非 OLE 自动化接口,开发人员可以编写自定义 RCW,手动将 COM 接口提供的类型映射为与 .NET 框架兼容的类型。
http://www.aspcool.com/lanmu/browse1.asp?ID=1129&bbsuser=aspnet
http://www.aspcool.com/lanmu/browse1.asp?ID=1130&bbsuser=aspnet
http://www.aspcool.com/lanmu/browse1.asp?ID=1131&bbsuser=aspnet
http://www.aspcool.com/lanmu/browse1.asp?ID=1132&bbsuser=aspnet
http://www.aspcool.com/lanmu/browse1.asp?ID=1133&bbsuser=aspnet
http://www.aspcool.com/lanmu/browse.asp?bbsuser=aspnet
建议看这个议论:
http://expert.csdn.net/expert/topic/2285/2285054.xml?temp=.1181757