gpt4 book ai didi

c# - 如何在 C# 中的 Dispose() 方法中处理托管资源?

转载 作者:可可西里 更新时间:2023-11-01 08:17:31 24 4
gpt4 key购买 nike

我知道 Dispose() 是为非托管资源设计的,当资源不再需要时应该被释放,而不用等待垃圾收集器完成对象。

但是,在处置对象时,它会抑制垃圾收集器的终结(在下面的代码中为 GC.SuppressFinalize(this);)。这意味着如果对象包含托管资源,我们也必须处理它,因为垃圾收集器不会清理它。

在下面的示例代码中(来自 MSDN),“Component”是一个托管资源,我们为此资源调用了 dispose() (component.Dispose())。我的问题是,我们如何为托管资源的组件类实现这个方法?我们是否应该使用像 Collect() 这样的东西来戳垃圾收集器来清理这部分?

任何想法将不胜感激。谢谢。

下面是我正在查看的来自 MSDN 的代码:

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.
private 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.
}
}

最佳答案

那个一次性模式是confusing .这是 a better way实现它:

第 1 步。 创建一个一次性类来封装您拥有的每个非托管资源。这应该是非常罕见的,大多数人没有非托管资源需要清理。本课only cares (pdf)关于它的非托管资源,并且应该有一个终结器。实现看起来像这样:

public class NativeDisposable : IDisposable {

public void Dispose() {
CleanUpNativeResource();
GC.SuppressFinalize(this);
}

protected virtual void CleanUpNativeResource() {
// ...
}

~NativeDisposable() {
CleanUpNativeResource();
}

// ...

IntPtr _nativeResource;

}

第 2 步。 当类(class)举办其他一次性类(class)时,创建一个一次性类(class)。这很容易实现,你不需要终结器。在您的 Dispose 方法中,只需对其他一次性用品调用 Dispose。在这种情况下,您不关心非托管资源:

public class ManagedDisposable : IDisposable {

// ...

public virtual void Dispose() {
_otherDisposable.Dispose();
}

IDisposable _otherDisposable;

}

示例中的“组件”可能是其中之一,具体取决于它是封装了非托管资源还是仅由其他一次性资源组成。

另请注意,抑制终结并不意味着您抑制垃圾收集器清理您的实例;这只是意味着当垃圾收集器在您的实例中运行时,它不会调用为其定义的终结器。

关于c# - 如何在 C# 中的 Dispose() 方法中处理托管资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2284626/

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