如何在C#中使用Dispose方法处理托管和非托管代码?

如何在C#中使用Dispose方法处理托管和非托管代码?

问题描述:

如何使用C#中的Dispose方法处理托管和非托管代码?



阅读完一篇文章后我才知道我们需要使用Dispose方法来清除垃圾。请参阅以下代码

How do i dispose managed and unmanged code using Dispose method in C#?

After reading some article i came to know that we need to use Dispose method to clear the garbage. See below code

public class abc: IDisposable
{ 
    public void Dispose();
    protected virtual void Dispose(bool disposing);
}




public void Dispose()
{
    Dispose(true);
    GC.SupressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if (!disposed)
    {
        if (disposing)
        {
            // Dispose managed resources.
        }

        // There are no unmanaged resources to release, but
        // if we add them, they need to be released here.
    }
    disposed = true;

    // If it is available, make the call to the
    // base class's Dispose(Boolean) method
    base.Dispose(disposing);
}



这里我们调用Dispose方法并调用Dispose(bool)。处理完后我们不需要Finalize所以我们正在做GC.SupressFinalize(这个);

我怀疑是,



无论如何,我们需要编写代码来处理非托管的管理代码吗?如下所示


here we are calling Dispose method and from that calling Dispose(bool).After disposing we do not need Finalize so we are doing GC.SupressFinalize(this);
My doubt is,

Anyway we need to write the code to dispose the unmanaged\managed code correct? like below

if (!disposed)
{
   if (disposing)
   {
       // Dispose managed resources. ---We need to write the code here to dispose the item right?
   }

   // There are no unmanaged resources to release, but
   // if we add them, they need to be released here.
}



那么Dispose方法在这里使用了什么?我们可以创建任何方法(使用其他名称)并将其调用为已发布。我们为什么要使用IDisposable接口?

我可以用我的自定义代码做正确的吗?


then what is the use of Dispose method here? we can create any method(With some other name) and call it to released. why should we use IDisposable interface ?
I can do it in my custom code correct?

首先,你没有展示整体IDisposable的实现。你错过了两个重要的部分:

1)对象的终结者方法

2) using statement [ ^ ]



完整的一次性模式应如下所示:

First, you are not showing the whole implementation of IDisposable. You are missing two important pieces to the puzzle:
1) Object's finalizer method
2) The using statement[^]

The full disposable pattern should look like this:
public void Dispose()
{
    Disposing(true);
}

private Dispose(bool disposing)
{
    if(disposing)
    {
        // release managed resources
        GC.SupressFinalize(this); // do not run finalizer, saves work for runtime
    }
    
    // release unmanaged resources
}

private ~MyClass() // the finalizer
{
    Dispose(false);
}



请注意,从dispose和finalize调用相同的方法。另请注意,只有在使用非托管资源时才需要实现所有这些功能。如果没有它们,它会变得更简单 - 你可以将所有逻辑直接放入Dispose()中而忘记其余部分。



为什么你应该使用IDisposable?因为您可以使用using语句:


Note that the same method is called from both dispose and finalize. Also note you need to implement all this only if you use unmanaged resources. Without them it gets a lot more simple - you can put all your logic directly into Dispose() and forget about the rest.

Why you should use IDisposable? Because you can the use the using statement:

using(var my = new MyClass())
{
    // my.Dispose() gets called at the end automatically
}



那么为什么呢你需要一个终结器?因为作为一个类的作者,你无法确定使用你的类的程序员会调用dispose还是使用。你无法强制执行它。因此,如果您使用某些非托管资源,则需要确保它们正确发布。那么Dispose()有什么用处可以自动处理?因为通常你想尽快释放资源,而不是等待GC启动。



CodeProject上有几篇关于IDisposable模式的好文章。最后一个很棒但非常技术性。不过我推荐它,因为解释为什么IDisposable实际上并不好。

* 理解和实现IDisposable接口 - 初学者教程 [ ^ ]

* 正确实现IDisposable和Dispose模式 [ ^ ]

* IDisposable:你的母亲从未告诉过你关于资源重新分配的事情 [ ^ ]


So why do you need a finalizer you ask? Because as the author of a class you cannot be sure that the programmers using your class will call dispose or use using. There is no way for you to enforce it. So if you use some unmanaged resources you want to make sure they get released properly. So what good is Dispose() if all can be taken care of automatically? Because generally you want to release resources as soon as possible, not wait for GC to kick in.

There are several good articles here on CodeProject about IDisposable pattern. The last one is great but very technical. Nevertheless I recommend it because of the explanation why IDisposable is actually not good.
* Understanding and Implementing IDisposable Interface - A Beginner's Tutorial[^]
* Implementing IDisposable and the Dispose Pattern Properly[^]
* IDisposable: What Your Mother Never Told You About Resource Deallocation[^]