Dispose vs Dispose(bool)

萝らか妹 提交于 2019-11-28 04:21:38

IDisposable provides a method with the signature

public void Dispose()

Microsoft best practices (http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx) recommend making a second private method with the signature

private void Dispose(bool)

Your public Dispose method and Finalizer should call this private Dispose method to prevent disposing managed resources multiple times.

You can fix the warning you are getting by either implementing IDisposable and disposing of your font object in the dispose method, or creating a Dispose(bool) method in your class, and make your finalizer call that method.

Kumar

Dispose(bool) is a pattern to implement Finalize and Dispose to Clean Up Unmanaged Resources , see this for detail

Dispose(bool) is not meant to be public and that is why you don't see it on Font.

In case some user of your class forgets to call Dispose on your method, you will release the unmanaged resources only by making a call to Dispose(false) in the Finalizer.

In case IDispose is called correctly, you call the Dispose on managed resources and also take care of the unmanaged.

The flag is to distinguish the two cases.

It is a pattern recommended by MSDN.

FxCop says you should implement the Disposable pattern like described here. Note that you should not use finalizers for disposing managed resources like _font is. Finalizers are used for cleaning up unmanaged resources. If you do not execute the cleanup logic in the Dispose method of your (sub)class they are executed non-deterministically by the garbage collector.

Also please note that it is very rarely that you need to do anything in the destructor. Regularly, everything is taken care of by the garbage collector. For example, in your code, you don't need to dispose the _font object in the OwnerDrawnPanel's destructor. Since the panel is getting cleaned up by the GC, so will be _font, because panel was the only one who referenced it, right?

Generally, if you own disposable objects, you only need to dispose them when your own Dispose method was called. But NOT in the destructor. When your destructor is running, you can bet that all your aggregated objects are being cleaned up as well.

You should almost never need to use finalizers. They are only for classes that directly contain unmanaged resources, and in .NET 2.0+ those should be wrapped in SafeHandle.

Ratnesh Sinha

I think Dispose(true) will free both the managed and unmanaged resource as we need to not call finalize again that's why we write GC.SupressFinalize() after Dispose(true).

We call Dispose(false) in destructors to free unmanaged resources and will be called by Runtime and not user's code.

Agreeing with Kumar, the Dispose(bool disposing) pattern is also documented on MSDN. The distinction is not between managed and unmanaged resources, but whether Dispose is being called by your code or the runtime.

I found a good article about correct implementation of IDispose interface: http://msdn.microsoft.com/en-us/library/ms244737(v=vs.80).aspx

The pattern of implementing a public public void Dispose(), protected virtual void Dispose(bool), and ~ClassName() finalizers is a best practice recommended by Microsoft as a way to neatly organize your cleanup code for both managed and unmanaged resources.

Basically, the code that uses your Disposable class should call Dispose(), but if it doesn't, the finalizer ~ClassName() will get called by Garbage Collection, and based on which one of those is used, you set the argument to Dispose(bool) as true or false, and in your Dispose(bool), you only clean up managed resources if the argument is true.

The warning you are getting seems to specifically recommend that you use this practice in your finalize method ~ClassName().

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!