Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Dispose и Finalize


Автор: Дрон 2.11.2005, 15:10
Как мне показалось, программисты в основном забивают на эти методы, надеясь на автоматический GC.

Вот, хочется выяснить, как обстоят дела с их использованием.

Вызываете ли вы Dispose для стандартных классов?
Пишите ли метод Dispose и деструкторы для собственных классов?

И какие вообще рекомендации существуют по этому поводу.

Автор: nikf 2.11.2005, 15:17
Если есть Dispose всегда его вызываю. Для свих класов делаю реализацию IDisposable толко в том случае если он сам содержит объекты реализующие IDisposable. Вот и все рекомендации. Врядли будут еще какие

Автор: Exception 2.11.2005, 15:19
вызываю. но своих не пишу, если нече2о освобождать

Автор: Дрон 2.11.2005, 15:20
Цитата(nikf @ 2.11.2005, 15:17)
Если есть Dispose всегда его вызываю. Для свих класов делаю реализацию IDisposable толко в том случае если он сам содержит объекты реализующие IDisposable. Вот и все рекомендации. Врядли будут еще какие

Естественно.

Просто недавно на собеседовании в одной компании у меня как раз возник спор об использовании Dispose smile
Да и в том проекте, где я сейчас занят -- на сотни тысяч строк практически ни одного Dispose smile smile

Автор: Plamenk 2.11.2005, 17:36
Dispose нужен только там, где есть неуправляемые объекты (в случае когда пишется пользоваетельский класс).
А что касается вызывать его или нет?
То вызывать конечно надо...
Но если не вызвать, то всё равно больших проблем не будет, так как его вызовет деструктор, но немного позже. smile

Автор: Exception 2.11.2005, 19:13
...который не обязательно выполнится. Ведь .NET не обеспечивает детерминированного завершения.

Автор: Plamenk 3.11.2005, 09:11
Цитата
...который не обязательно выполнится. Ведь .NET не обеспечивает детерминированного завершения.


Ты хочешь сказать, что NET не гарантирует вызов деструктора?

Автор: Дрон 3.11.2005, 09:33
Цитата(Plamenk @ 3.11.2005, 09:11)
Ты хочешь сказать, что NET не гарантирует вызов деструктора?

Гарантирует. Но в какой именно момент -- неизвестно.

Автор: Plamenk 3.11.2005, 09:43
Цитата
Но если не вызвать, то всё равно больших проблем не будет, так как его вызовет деструктор, но немного позже.

Так и я о том же smile

Автор: Exception 3.11.2005, 10:32
ага. "Немного позже" == при выгрузке AppDomain

Автор: Plamenk 3.11.2005, 10:46
А что деструкторы вызваются при
Цитата
при выгрузке AppDomain
?

А я думал что, при сборке муссора. Хотя могу ошибаться smile

Автор: Exception 3.11.2005, 14:17
дык сборка мусора и происходит при выгрузке домена приложения. И то не всегда. Создай консольное приложение, напиши класс типа
Код

Class X
Protected Overrides Sub Finalize()
MsgBox("Я СДОХ!")
End Sub
End Class

и насоздавай кучу таких объектиков. Не факт, что ты увидишь какие-то сообщения.
ЗЫ деструктор в С++ != завершитель в С#. Надо это помнить

Автор: Plamenk 3.11.2005, 15:27
Посмотри за окном output. У меня не разу не получилось, чтобы хотябы для одного объекта не вызвался деструктор.


Код

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using System.Data;

namespace TestGC
{
    /// <summary>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Button button1;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.Container components = null;

        public Form1()
        {
            //
            // Required for Windows Form Designer support
            //
            InitializeComponent();

            //
            // TODO: Add any constructor code after InitializeComponent call
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.button1 = new System.Windows.Forms.Button();
            this.SuspendLayout();
            // 
            // button1
            // 
            this.button1.Location = new System.Drawing.Point(168, 56);
            this.button1.Name = "button1";
            this.button1.Size = new System.Drawing.Size(80, 24);
            this.button1.TabIndex = 0;
            this.button1.Text = "button1";
            this.button1.Click += new System.EventHandler(this.button1_Click);
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.button1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.ResumeLayout(false);

        }
        #endregion

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main() 
        {
            Application.Run(new Form1());
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            TestGC obj;
            for (int i=0; i<10000; i++)
                obj = new TestGC(); 
        }
    }

    public class TestGC
    {
        static int i = 0;
        public TestGC()
        {
            i+=1;
            Trace.WriteLine(i.ToString());   
        }

        ~TestGC()
        {
            i-=1;
            Trace.WriteLine(i.ToString());   
        }

        
    }
}


Может в VB.Net, что-то по другому?

Автор: Exception 3.11.2005, 20:52
может я и ошибаюсь...
компа нета проверить...
мне казалось, GC происходит не всегда

Автор: mr.DUDA 4.11.2005, 10:23
GC, вообще-то, собирает мусор только в двух случаях:
а) когда он посчитает, что свободной памяти ему маловато (10000 таких объектов - это что-то вроде 40-60 Кб)
б) когда приложение простаивает

Принудительно можно вызвать цикл сборки мусора с пом. GC.Collect(), тогда и увидим сообщения из деструкторов.

З.Ы.

Цитата(Run @ 3.11.2005, 10:32)
ага. "Немного позже" == при выгрузке AppDomain

Цитата(Run @ 3.11.2005, 14:17)
дык сборка мусора и происходит при выгрузке домена приложения. И то не всегда.

Сборка мусора происходит периодически, при выполнении условий а) и б). При выгрузке домена приложения вся выделенная ему память освобождается целиком.

Автор: -ser- 7.11.2005, 08:36
что касается Finalize, то его по многим причинам не рекомендуется вообще использовать если нет на это острой необходимости. и даже в объектах, работающих c unmanaged ресурсами, если корректно закрывать файл, поток или соединение в сети, то я считаю, даже и здесь его лучше не упоминать. вообще, объекты с этим методом занимает больше по времени разместить и также удалить, что может значительно сказаться на быстродействии. ГК нужно запуститься по меньшей мере 2 раза чтобы полностью удалить такой объект, причем удаляется каждый такой объект по-отдельности, а что если у нас массив из 10000 таких объектов.

Автор: Exception 8.11.2005, 15:36
кстати,
[offtop]
я так и не понял, как ловить исключения, вызванные финалайзером. они же не ловятся обычным способом (т.к. в другом потоке)...
[/offtop]

Автор: -ser- 10.11.2005, 07:06
Run-time error
Цитата
как ловить исключения, вызванные финалайзером
насколько я знаю, само исключение, вызванное финалайзером игнорируется рантаймом.

Автор: Exception 10.11.2005, 14:31
не-а.
я пробовал вроде такого:
Код

Class X
Protected Overrides Sub Finalize()
Throw New ApplicationException("FUCK YOU!")
End Sub
End Class
Module main
Sub Main
Try
Dim myX As New X()
myX = Nothing
GC.Collect()
Catch e as Exception
End Try
Console.ReadLine()
End Sub
End Module

эксепшн лез

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)