问题描述
C# 2008
我已经为此工作了一段时间,但我仍然对在代码中使用 finalize 和 dispose 方法感到困惑.我的问题如下:
I have been working on this for a while now, and I am still confused about the use of finalize and dispose methods in code. My questions are below:
我知道在处理非托管资源时我们只需要一个终结器.但是,如果有托管资源调用非托管资源,是否还需要实现终结器?
I know that we only need a finalizer while disposing unmanaged resources. However, if there are managed resources that make calls to unmanaged resources, would it still need to implement a finalizer?
但是,如果我开发一个不直接或间接使用任何非托管资源的类,我是否应该实现 IDisposable
以允许该类的客户端使用使用陈述'?
However, if I develop a class that doesn't use any unmanaged resource - directly or indirectly, should I implement the IDisposable
to allow the clients of that class to use the 'using statement'?
实现 IDisposable 只是为了让你的类的客户能够使用 using 语句是否可行?
Would it be feasible to implement IDisposable just to enable clients of your class to use the using statement?
using(myClass objClass = new myClass())
{
// Do stuff here
}
我在下面开发了这个简单的代码来演示 Finalize/dispose 的使用:
I have developed this simple code below to demonstrate the Finalize/dispose use:
public class NoGateway : IDisposable
{
private WebClient wc = null;
public NoGateway()
{
wc = new WebClient();
wc.DownloadStringCompleted += wc_DownloadStringCompleted;
}
// Start the Async call to find if NoGateway is true or false
public void NoGatewayStatus()
{
// Start the Async's download
// Do other work here
wc.DownloadStringAsync(new Uri(www.xxxx.xxx));
}
private void wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
// Do work here
}
// Dispose of the NoGateway object
public void Dispose()
{
wc.DownloadStringCompleted -= wc_DownloadStringCompleted;
wc.Dispose();
GC.SuppressFinalize(this);
}
}
关于源代码的问题:
这里我没有添加finalizer,一般情况下finalizer会被GC调用,finalizer会调用Dispose.由于我没有终结器,我什么时候调用 Dispose 方法?是必须调用它的类的客户端吗?
Here I have not added the finalizer, and normally the finalizer will be called by the GC, and the finalizer will call the Dispose. As I don't have the finalizer, when do I call the Dispose method? Is it the client of the class that has to call it?
所以我在示例中的类称为 NoGateway,客户端可以像这样使用和处置该类:
So my class in the example is called NoGateway and the client could use and dispose of the class like this:
using(NoGateway objNoGateway = new NoGateway())
{
// Do stuff here
}
在执行到 using 块的末尾时会自动调用 Dispose 方法,还是客户端必须手动调用 dispose 方法?即
Would the Dispose method be automatically called when execution reaches the end of the using block, or does the client have to manually call the dispose method? i.e.
NoGateway objNoGateway = new NoGateway();
// Do stuff with object
objNoGateway.Dispose(); // finished with it
我在我的 NoGateway
类中使用 WebClient
类.因为WebClient
实现了IDisposable
接口,这是否意味着WebClient
间接使用了非托管资源?是否有严格的规则来遵循这一点?我如何知道某个类使用了非托管资源?
I am using the WebClient
class in my NoGateway
class. Because WebClient
implements the IDisposable
interface, does this mean that WebClient
indirectly uses unmanaged resources? Is there a hard and fast rule to follow this? How do I know that a class uses unmanaged resources?
推荐答案
推荐的 IDisposable 模式是 这里.在编写使用 IDisposable 的类时,通常应该使用两种模式:
The recommended IDisposable pattern is here. When programming a class that uses IDisposable, generally you should use two patterns:
当实现一个不使用非托管资源的密封类时,您只需像普通接口实现一样实现一个 Dispose 方法:
When implementing a sealed class that doesn't use unmanaged resources, you simply implement a Dispose method as with normal interface implementations:
public sealed class A : IDisposable
{
public void Dispose()
{
// get rid of managed resources, call Dispose on member variables...
}
}
当实现一个非密封类时,这样做:
When implementing an unsealed class, do it like this:
public class B : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// get rid of managed resources
}
// get rid of unmanaged resources
}
// only if you use unmanaged resources directly in B
//~B()
//{
// Dispose(false);
/