最终确定/ Dispose模式用C# [英] Finalize/Dispose pattern in C#

查看:184
本文介绍了最终确定/ Dispose模式用C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#2008

我一直对这个有一段时间了。而我仍然感到困惑的一些问题。以下

我的问题
  1. 我知道,你只需要一个终结,如果你是处置非托管资源。但是,如果您使用的是管理资源进行调用非托管资源。你仍然需要实现一个终结?

  2. 不过,如果你开发,不直接或间接使用任何非托管资源类,你实现了的IDisposable ,以便您的类的客户端可以使用在使用声明。

    难道是可以接受的实现IDisposable只是让你的类的客户端可以使用using语句?

     使用(MyClass的objClass =新MyClass的())
    {
        //这里做的东西
    }
     

  3. 我已经开发了这个简单的code以下,以展示的Finalize / Dispose模式:

     公共类NoGateway:IDisposable的
    {
        私人WebClient的WC = NULL;
    
        公共NoGateway()
        {
            WC =新的Web客户端();
            wc.DownloadStringCompleted + = wc_DownloadStringCompleted;
        }
    
    
        //启动异步调用找到,如果NoGateway是真还是假
        公共无效NoGatewayStatus()
        {
            //启动异步的下载
                //做其他工作在这里
            wc.DownloadStringAsync(新的URI(www.xxxx.xxx));
        }
    
        私人无效wc_DownloadStringCompleted(对象发件人,DownloadStringCompletedEventArgs E)
        {
            //这里做的工作
        }
    
        //处置NoGateway对象
        公共无效的Dispose()
        {
            wc.DownloadStringCompleted  -  = wc_DownloadStringCompleted;
            wc.Dispose();
            GC.Sup pressFinalize(本);
        }
    }
     

有关源$ C ​​$ C问:

  1. 在这里,我还没有添加终结。而且通常将终结由GC被调用,终结会调用Dispose。由于我没有终结,我什么时候调用Dispose方法?难道有打电话了吗?之类的客户端

    所以,我在这个例子类称为NoGateway和客户端可以使用和处置类像这样的:

     使用(NoGateway objNoGateway =新NoGateway())
    {
        //这里做的东西
    }
     

    请问Dispose方法被自动执行时到达using块到底叫什么?还是客户端必须手动调用Dispose方法,即?

      NoGateway objNoGateway =新NoGateway();
    //做的东西与对象
    objNoGateway.Dispose(); //用它完成
     

  2. 我是用我的 NoGateway 类WebClient类。由于Web客户端实现了IDisposable接口。这是否意味着Web客户端间接使用非托管资源?有没有硬性规定要遵循这一点。我怎么知道,一类使用非托管资源?

解决方案

建议IDisposable模式是的此处。在编程时使用IDisposable的一类,通常你应该使用两种模式:

在实现不使用非托管资源密封类,只需实现Dispose方法与普通的接口实现:

 公共密封类答:IDisposable的
{
    公共无效的Dispose()
    {
        //摆脱管理的资源,调用Dispose成员变量...
    }
}
 

在实施非密封类,像这样做:

 大众B级:IDisposable的
{
    公共无效的Dispose()
    {
        处置(真);
        GC.Sup pressFinalize(本);
    }

    受保护的虚拟无效的Dispose(BOOL处置)
    {
        如果(处置)
        {
            //摆脱管理的资源
        }
        //摆脱非托管资源
    }

    //只有当你直接在B之间使用非托管资源
    //〜B()
    // {
    //处置(假);
    //}
}
 

请注意,我还没有宣布终结在 B ;你应该只,如果你有实际的非托管资源处置实现一个终结。 CLR的处理终结对象不同,以非终结对象,即使燮pressFinalize 之称。

所以,你不应该宣告终结,除非你有,但你给你的类继承钩打电话给你的处置,如果他们实施一个终结自己直接使用非托管资源:

 公共类C:将B
{
    私人IntPtr的m_Handle;

    保护覆盖无效的Dispose(BOOL处置)
    {
        如果(处置)
        {
            //摆脱管理的资源
        }
        ReleaseHandle(m_Handle);

        base.Dispose(处置);
    }

    〜C(){
        处置(假);
    }
}
 

如果你不直接使用非托管资源(的SafeHandle 和朋友不算数,因为他们宣称自己的终结),则没有实现一个终结,作为GC处理终结班不同,即使你以后燮preSS终结。还要注意的是,尽管 B 没有终结,它仍称燮pressFinalize 正确处理与国家执行终结任何子类。

当一个类实现IDisposable接口,这意味着,地方有应摆脱当你使用类已经完成了一些非托管资源。实际的资源类包裹内;你并不需要显式删除它们。简单地调用的Dispose()或包装类的使用(...){} 将确保所有非托管资源摆脱了必要的。

C# 2008

I have been working on this for a while now. And I am still confused about some issues. My questions below

  1. I know that you only need a finalizer if you are disposing of unmanaged resources. However, if you are using managed resources that make calls to unmanaged resources. Would you still need to implement a finalizer?

  2. However, if you develop a class that doesn't use any unmanaged resources directly or indirectly and you implement the IDisposable so that clients of your class can use the 'using statement'.

    Would it be acceptable to implement the IDisposable just so that clients of your class can use the using statement?

    using(myClass objClass = new myClass())
    {
        // Do stuff here
    }
    

  3. I have developed this simple code below to demonstrate the Finalize/dispose pattern:

    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);
        }
    }
    

Question about the source code:

  1. 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?

    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   
    }
    

    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
    

  2. I am using the webclient class in my NoGateway class. Because the webclient implements the IDisposable interface. Does this mean that the webclient indirectly uses unmanaged resources? Is there any hard and fast rule to follow about this. How do I know that a class uses unmanaged resources?

解决方案

The recommended IDisposable pattern is here. When programming a class that uses IDisposable, generally you should use two patterns:

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);
    //}
}

Notice that I haven't declared a finalizer in B; you should only implement a finalizer if you have actual unmanaged resources to dispose. The CLR deals with finalizable objects differently to non-finalizable objects, even if SuppressFinalize is called.

So, you shouldn't declare a finalizer unless you have to, but you give inheritors of your class a hook to call your Dispose and implement a finalizer themselves if they use unmanaged resources directly:

public class C : B
{
    private IntPtr m_Handle;

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            // get rid of managed resources
        }
        ReleaseHandle(m_Handle);

        base.Dispose(disposing);
    }

    ~C() {
        Dispose(false);
    }
}

If you're not using unmanaged resources directly (SafeHandle and friends doesn't count, as they declare their own finalizers), then don't implement a finalizer, as the GC deals with finalizable classes differently, even if you later suppress the finalizer. Also note that, even though B doesn't have a finalizer, it still calls SuppressFinalize to correctly deal with any subclasses that do implement a finalizer.

When a class implements the IDisposable interface, it means that somewhere there are some unmanaged resources that should be got rid of when you've finished using the class. The actual resources are encapsulated within the classes; you don't need to explicitly delete them. Simply calling Dispose() or wrapping the class in a using(...) {} will make sure any unmanaged resources are got rid of as necessary.

这篇关于最终确定/ Dispose模式用C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆