IDisposable的实现 - 我应该去'如果(处置)“ [英] IDisposable implementation - What should go in 'if (disposing)'

查看:163
本文介绍了IDisposable的实现 - 我应该去'如果(处置)“的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经修复了一些内存泄漏问题的WinForms应用程序,发现未显式释放一些一次性的对象(发展商并没有所谓的Dispose方法)。定案方法的实现也没有帮助,因为它并不重要,如果(处置)子句进去。所有静态事件取消注册和收集结算已实施如果(处置)条款。最好的做法是调用的Dispose如果对象是一次性的,但不幸的是这种情况,有时

如果有非托管对象,静态的事件处理程序和一些管理的集合,需要明确处置时。什么是决定什么应该去的,应该怎么走出如果(处置)条款的方式。

Dispose方法。

  //的Dispose(BOOL处置)执行两种不同的场景。
//如果要撤除等于true,该方法已被直接调用
//或间接地由用户的code。托管和非托管资源
//可以设置。
//如果要撤除等于false,该方法被调用的
从终结里面//运行时,你不应该引用
//其他对象。只有非托管资源可以配置。
受保护的虚拟无效的Dispose(BOOL处置)
{
    如果(!处置)
    {
        如果(处置)
        {
            //自由其他国家(管理对象)。
        }

         //释放你自己的状态(非托管对象)。
         //设置大字段设置为null。
         处置= TRUE;
     }
 }
 

它说管理对象应在如果(处置)其执行通常只有当开发人员显式调用Dispose方法。如果Finalize方法已经实施和开发者忘记调用Dispose方法来这里通过终结执行不进去如果(处置)部分。

下面是我的问题。

  1. 如果我有静态的事件处理程序,导致内存泄漏我应该在哪里注销呢?或缩小如果(处置)条款?

  2. 如果我有一些收藏品,导致我应该清除这些内存泄漏?或缩小如果(处置)条款?

  3. 如果我使用第三方处置的对象(如:devEx preSS的WinForm控件),我不知道他们是否托管或非托管对象。比方说,我想,当处理一个表单来处理它们。我怎么知道是什么管理,什么是不可管理的对象?是一次性使用的不说吗?在这种情况下,如何决定什么应该在什么应该走出去的如果(处置)条款?

  4. 如果我不知道的东西托管或非托管有什么方法可以处理/结算/注销,事件出了如果(处置)条款的不良后果?比方说,它会检查空处理过吗?

修改

我的意思是事件未登记是类似下面。发布者是一个长期的生活实例,下面一行是在用户的构造。在这种情况下,用户需要注销事件和出版商提前处理。

  publisher.DoSomeEvent + = subscriber.DoSomething;
 

解决方案
  

我应该去'如果(处置)

所有管理对象应该往里走,如果(处置)条款。管理对象不应该出来的一侧(将通过终结执行)。

原因在于,垃圾收集器最终处理可以执行的Dispose(假)如果类有析构函数。通常有一个析构函数只有在有非托管resources.Garbage收藏家的定稿并没有一个特定的顺序执行Finalize方法。因此,其他被管理对象可能不会在内存中最终确定发生的时间。

I have been fixing some memory leak issues in a winforms application and noticed some disposable objects that are not Disposed explicitly (developer hasn't called Dispose method). Implementation of Finalize method also doesn't help because it doesn't go in if (disposing) clause. All the static event unregistering and collection clearing have been put in if (disposing) clause. The best practice is calling the Dispose if the object is disposable, but unfortunately this happens sometimes

If there are unmanaged objects, static event handlers and some managed collections that needs to clear when disposing. What's the way to decide what should go in and what should go out of if (disposing) clause.

Dispose method.

// 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.
protected virtual void Dispose(bool disposing)
{
    if (!disposed)
    {
        if (disposing)
        {
            // Free other state (managed objects).
        }

         // Free your own state (unmanaged objects).
         // Set large fields to null.
         disposed = true;
     }
 }

It says managed objects should in if (disposing) which executes normally only when explicitly call Dispose method by the developer. If the Finalize method has been implemented and developer forgets to call the Dispose method the execution that comes here through the Finalizer does not go in if (disposing) section.

Below are my questions.

  1. If I have static event handlers that causes memory leaks where should I un-register them? In or out of if (disposing) clause?

  2. If I have some collections that causes memory leaks where should I clear them? In or out of if (disposing) clause?

  3. If I am using third party disposable objects (eg: devExpress winform controls) that I am not sure whether they are managed or unmanaged objects. Let's say I want to dispose them when disposing a form. How can I know what are managed and what are non-managed objects? Being disposable doesn't say that? In such cases how to decide what should go in and what should go out of if (disposing) clause?

  4. If I am not sure something managed or unmanaged what can be the bad consequences of disposing/clearing/unregistering-events out of the if (disposing) clause? Let's say it checks for null before disposing?

Edit

What I mean as event un-registering is something like below. Publisher is a long lived instance and below line is in the subscriber's constructor. In this case subscriber need to unregister the event and dispose before the publisher.

publisher.DoSomeEvent += subscriber.DoSomething;

解决方案

What should go in 'if (disposing)'

All Managed objects should go inside if(disposing) clause. Managed objects should not go out side of it (which will be executed through the finalization).

The reason is that Garbage collectors finalization process can execute the Dispose(false) if that class has a Destructor. Normally there is a Destructor only if there are unmanaged resources.Garbage collector's finalization doesn't have a particular order to execute the Finalize method. So, other managed objects may not be in memory by the time finalization occurs.

这篇关于IDisposable的实现 - 我应该去'如果(处置)“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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