В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 18.10.08 15:50
Оценка:
Что же это получается? Вызов деструктора неопределен не только по времени, но и по количеству? У меня на один вызов конструктора COM объекта по 300 вызовов деструктора. Я в панике
Re: В каком случае деструктор вызывается несколько раз?
От: adontz Грузия http://adontz.wordpress.com/
Дата: 18.10.08 15:54
Оценка: +1
Здравствуйте, visus, Вы писали:

V>Что же это получается? Вызов деструктора неопределен не только по времени, но и по количеству? У меня на один вызов конструктора COM объекта по 300 вызовов деструктора. Я в панике


В .Net Framework нет деструктора. Есть финалайзер и IDisposable.Dispose, оба могут быть вызваны много раз.
В COM нет деструтора, есть IUnknown.Release. Должен быть вызван столько же раз, сколько IUnknown.AddRef, то есть, может быть вызван много раз.

О чём речь вообще?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[2]: В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 18.10.08 16:14
Оценка:
A>О чём речь вообще?

Вот об этом: Destructors (C# Programming Guide)
Re: В каком случае деструктор вызывается несколько раз?
От: drol  
Дата: 18.10.08 16:37
Оценка:
Здравствуйте, visus, Вы писали:
V>У меня на один вызов конструктора COM объекта по 300 вызовов деструктора. Я в панике

Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.
Re[2]: В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 18.10.08 17:05
Оценка:
D>Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.

Было бы чего показывать:

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("PSM.Folder")]
[Guid("43933A80-32DF-436c-8296-FF16B4A32A01")]
public class SomeObject
...

public SomeObject()
{
FileStream file = File.Open("somename.txt", FileMode.Append, FileAccess.Write, FileShare.Read);
Encoding enc1251 = Encoding.GetEncoding(1251);
StreamWriter sw = new StreamWriter(file, enc1251); // Why stack overflow?
sw.WriteLine("call constructor");
sw.Flush();
sw.Close();
}


~SomeObject()
{
FileStream file = File.Open("somename.txt", FileMode.Append, FileAccess.Write, FileShare.Read);
Encoding enc1251 = Encoding.GetEncoding(1251);
StreamWriter sw = new StreamWriter(file, enc1251); // Why stack overflow?
sw.WriteLine("call destructor");
sw.Flush();
sw.Close();
}

Создание:
object AObject = Activator.CreateInstance(TypeByGUID);

Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.
Re[3]: В каком случае деструктор вызывается несколько раз?
От: TK Лес кывт.рф
Дата: 18.10.08 17:17
Оценка:
Здравствуйте, visus, Вы писали:

A>>О чём речь вообще?

V>Вот об этом: Destructors (C# Programming Guide)

Автор случайно не Григорий Остер?
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[4]: В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 18.10.08 17:26
Оценка: :)
TK>Автор случайно не Григорий Остер?

Минус решил не ставить. RTFM.
Re[3]: В каком случае деструктор вызывается несколько раз?
От: Pavel M. Россия  
Дата: 18.10.08 17:29
Оценка:
Здравствуйте, visus, Вы писали:

D>>Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.


V>Было бы чего показывать:


V>Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.


На указанных местах вылетает StackOverflow? А Вы пробовали с другой кодировкой писать, например Encoding.Unicode?
Что в файлах?

И почитайте про using
--------------------------
less think — do more
Re[4]: В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 18.10.08 17:36
Оценка:
V>>Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.

PM>На указанных местах вылетает StackOverflow? А Вы пробовали с другой кодировкой писать, например Encoding.Unicode?

PM>Что в файлах?

Это простая тестовая программа. Когда я её запускал под отладкой, то в некоторых случаях возникал StackOverflow на указанной строке. Воспроизводить не удается. Пока идей нет. Нет, unicode не пробовал.

PM>И почитайте про using


Вот тут подробнее пожалуйста. Где в данном коде нужен using? Я не вижу тут места для его применения.
Re[5]: В каком случае деструктор вызывается несколько раз?
От: Pavel M. Россия  
Дата: 18.10.08 17:48
Оценка:
Здравствуйте, visus, Вы писали:

V>>>Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.


PM>>На указанных местах вылетает StackOverflow? А Вы пробовали с другой кодировкой писать, например Encoding.Unicode?

PM>>Что в файлах?

V>Это простая тестовая программа. Когда я её запускал под отладкой, то в некоторых случаях возникал StackOverflow на указанной строке. Воспроизводить не удается. Пока идей нет. Нет, unicode не пробовал.


System.Text.Encoding.Unicode
попробуйте для теста, вместо того, что у Вас написано.


The .NET Framework provides the following implementations of the Encoding class to support current Unicode encodings and other encodings:
*
ASCIIEncoding encodes Unicode characters as single 7-bit ASCII characters. This encoding only supports character values between U+0000 and U+007F. Code page 20127. Also available through the ASCII property.
*
UTF7Encoding encodes Unicode characters using the UTF-7 encoding. This encoding supports all Unicode character values. Code page 65000. Also available through the UTF7 property.
*
UTF8Encoding encodes Unicode characters using the UTF-8 encoding. This encoding supports all Unicode character values. Code page 65001. Also available through the UTF8 property.
*
UnicodeEncoding encodes Unicode characters using the UTF-16 encoding. Both little endian (code page 1200) and big endian (code page 1201) byte orders are supported. Also available through the Unicode property and the BigEndianUnicode property.
*
UTF32Encoding encodes Unicode characters using the UTF-32 encoding. Both little endian (code page 12000) and big endian (code page 12001) byte orders are supported. Also available through the UTF32 property.


здесь


PM>>И почитайте про using


V>Вот тут подробнее пожалуйста. Где в данном коде нужен using? Я не вижу тут места для его применения.


using statement
Применяйте всегда (за редким исключением), когда работаете с классами, реализующими IDisposable, потоки к ним относятся (FileStream etc).
--------------------------
less think — do more
Re[4]: В каком случае деструктор вызывается несколько раз?
От: Pavel M. Россия  
Дата: 18.10.08 17:51
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, visus, Вы писали:


A>>>О чём речь вообще?

V>>Вот об этом: Destructors (C# Programming Guide)

TK>Автор случайно не Григорий Остер?


Кстати, я тоже удивлен. Посмотрите

Desctructors (C#)
--------------------------
less think — do more
Re[6]: В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 18.10.08 17:59
Оценка:
Я не вижу как ваши ответы могут соотноситься с сутью вопроса.
Что может быть не так с codepage 1251? В вашей практике были какие-то примеры?
Про using я поторяю вопрос: приведите пример, как бы вы в указанном коде использовали using?
Коллеги, я прошу серьезнее отнестись к вопросу.
По поводу множественных вызовов деструктора у меня есть поверхностное предположение: возможно, если в деструкторе возникает исключение, то машинка считает финализацию объекта незавершенной и оставляет в очереди. Но в данном коде исключению взяться неоткуда, всё должно работать. И результат работы этого кода я вижу в файле. FW 2.0
Re[5]: В каком случае деструктор вызывается несколько раз?
От: adontz Грузия http://adontz.wordpress.com/
Дата: 18.10.08 18:31
Оценка:
Здравствуйте, Pavel M., Вы писали:

PM>Кстати, я тоже удивлен. Посмотрите

PM>Desctructors (C#)

ИМХО путаница в терминологии. С одной стороны "The destructor implicitly calls Finalize on the object's base class.", с другой стороны "Finalize on the object's base class." это "деструктор" базового класса.

Деструктор, в понимании Си++ в .Net отсутствует. Удаление объекта происходит в недетерминированный момент времени, соответственно нет служебного метода, вызываемого при удалении момента в детерминированный момент времени.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: В каком случае деструктор вызывается несколько раз?
От: _FRED_ Черногория
Дата: 18.10.08 18:46
Оценка:
Здравствуйте, visus, Вы писали:

D>>Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.

V>Было бы чего показывать:
[c#]
V>StreamWriter sw = new StreamWriter(file, enc1251); // Why stack overflow?
[/c#]

Call Stack в точке возникновения "stack overflow" давай посмотрим.
Help will always be given at Hogwarts to those who ask for it.
Re[6]: В каком случае деструктор вызывается несколько раз?
От: Pavel M. Россия  
Дата: 18.10.08 18:52
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Pavel M., Вы писали:


A>Деструктор, в понимании Си++ в .Net отсутствует. Удаление объекта происходит в недетерминированный момент времени, соответственно нет служебного метода, вызываемого при удалении момента в детерминированный момент времени.


Да что Вы мне-то это рассказывайте, я это прекрасно знаю. Просто думал, что это они же ввели понятие "финализатор" и порекомендовали не употреблять "деструктор", этому и удивляюсь)
--------------------------
less think — do more
Re[7]: В каком случае деструктор вызывается несколько раз?
От: Pavel M. Россия  
Дата: 18.10.08 18:56
Оценка:
Здравствуйте, visus, Вы писали:

V>Я не вижу как ваши ответы могут соотноситься с сутью вопроса.

V>Что может быть не так с codepage 1251? В вашей практике были какие-то примеры?
V>Про using я поторяю вопрос: приведите пример, как бы вы в указанном коде использовали using?
V>Коллеги, я прошу серьезнее отнестись к вопросу.
V>По поводу множественных вызовов деструктора у меня есть поверхностное предположение: возможно, если в деструкторе возникает исключение, то машинка считает финализацию объекта незавершенной и оставляет в очереди. Но в данном коде исключению взяться неоткуда, всё должно работать. И результат работы этого кода я вижу в файле. FW 2.0

Во-первых, сейчас суббота и я вобще удивлен, что кто-то не отдыхает)
Во-вторых, мне кажется GetEncoding(1251) может давать немного не то, что Вы ожидаете, но я не до конца силен в кодировках, поэтому и говорю попробовать стандартную. Вы понимаете, что метдом проб и ошибок некоторые вещи должны решаться. Про using я Вам дал ссылку, хотя достаточно было одного упоминания слова, чтобы Вы сами поискали. Читаете по-английски? Тогда возьмите и почитайте. А еще к этому почитайте какую-нибудь книгу по платформе и языку, допустим Рихтер, Петцольд, можно даже Троелсена, Нэш... Такие вопросы базовые отпадут одномоментно.

> всё должно работать.


Работает?
--------------------------
less think — do more
Re[6]: В каком случае деструктор вызывается несколько раз?
От: drol  
Дата: 19.10.08 05:58
Оценка:
Здравствуйте, adontz, Вы писали:

A>ИМХО путаница в терминологии. С одной стороны "The destructor implicitly calls Finalize on the object's base class.", с другой стороны "Finalize on the object's base class." это "деструктор" базового класса.


Никакой путаницы нет. Выше там чётко написано: "Destructors cannot be inherited or overloaded". Дальше не менее чётко написано, что код деструктора транслируется в следующее:
protected override void Finalize()
{
    try
    {
        // Cleanup statements...
    }
    finally
    {
        base.Finalize();
    }
}

Если же Вы попробуете явно перекрыть Finalize(), то получите ошибку от компилятора "напишите вместо Finalize() деструктор".

A>Деструктор, в понимании Си++ в .Net отсутствует. Удаление объекта происходит в недетерминированный момент времени, соответственно нет служебного метода, вызываемого при удалении момента в детерминированный момент времени.


М-да-а-а... Ну и каша в головах... Зачем нам метод для детерминированного момента, ежели удаляем в недетерминированный ??? Всё так же как в C++: когда реально удаляем, тогда и вызываем служебный метод.

Ключевое свойство деструкторов вовсе не детерминированность какого-то там момента, а то что они вызываются runtime'ом вне нормального контекста исполнения кода. Что, по-совместительству, и является их основной проблемой.
Re[8]: В каком случае деструктор вызывается несколько раз?
От: visus  
Дата: 19.10.08 06:15
Оценка: -2 :)
PM>Во-вторых, мне кажется GetEncoding(1251) может давать немного не то, что Вы ожидаете, но я не до конца силен в кодировках, поэтому и говорю попробовать стандартную. Вы понимаете, что метдом проб и ошибок некоторые вещи должны решаться.

Код соответствует MSDN, файл пишется в нужной кодировке. Описание GetEncoding(1251) можете посмотреть сами.

> Про using я Вам дал ссылку, хотя достаточно было одного упоминания слова, чтобы Вы сами поискали. Читаете по-английски? Тогда возьмите и почитайте. А еще к этому почитайте какую-нибудь книгу по платформе и языку, допустим Рихтер, Петцольд, можно даже Троелсена, Нэш... Такие вопросы базовые отпадут одномоментно.


Прочитайте пожалуйста ветку с начала. Я не искал ничего про using, вы сами себя ввели в заблуждение. И то, что вы не знали про существование "Destructors" в понимании C#, говорит о том, что вы не совсем владеете темой вопроса.

>> всё должно работать.


PM>Работает?


Работает. Вас это беспокоит? Вы хотите об это поговорить? Я в общем-то не против.
Re[7]: В каком случае деструктор вызывается несколько раз?
От: adontz Грузия http://adontz.wordpress.com/
Дата: 19.10.08 07:06
Оценка:
Здравствуйте, drol, Вы писали:

D>Дальше не менее чётко написано, что код деструктора транслируется в следующее:


Следующее как раз финалайзер и есть.

D>М-да-а-а... Ну и каша в головах... Зачем нам метод для детерминированного момента, ежели удаляем в недетерминированный ??? Всё так же как в C++: когда реально удаляем, тогда и вызываем служебный метод.


Забавно, и это у меня каша. Метод нужен, почитай про IDisposable. Просто в отличие от Си++, его приходится выхывать вручную.

D>Ключевое свойство деструкторов вовсе не детерминированность какого-то там момента, а то что они вызываются runtime'ом вне нормального контекста исполнения кода. Что, по-совместительству, и является их основной проблемой.


Это свойство финалайзеров, в рантайме никаких деструкторов нет.
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: В каком случае деструктор вызывается несколько раз?
От: Neco  
Дата: 19.10.08 07:14
Оценка:
D>>Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.
V>Было бы чего показывать:
Ваш код у меня отказался работать (одновременный доступ к файлу) — я его немного переделал и вот в таком виде он ошибок не выдаёт.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;

namespace ConsoleApplication1 {
    class Program {
        static void Main(string[] args) {
            for (int i = 0; i < 100; i++) {
                ManyTimes();
                GC.Collect();
            }
        }
        private static void ManyTimes() {
            for (int i = 0; i < 100; i++) {
                ComTest inst = new ComTest();
            }
        }
    }

    [ComVisible(true)]
    [ClassInterface(ClassInterfaceType.None)]
    [ProgId("PSM.Folder")]
    [Guid("43933A80-32DF-436c-8296-FF16B4A32A01")]
    class ComTest {
        public ComTest() {
            WriteLog("call constructor");
        }


        ~ComTest() {
            WriteLog("call destructor");
        }
        private static object _sync_obj = new object();
        private void WriteLog(string line) {
            lock (_sync_obj) {
                using (FileStream file = new FileStream(@"g:\somename.txt", FileMode.Append | FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) {
                    using (StreamWriter sw = new StreamWriter(file, Encoding.GetEncoding(1251))) {
                        sw.WriteLine(line);
                    }
                }
            }
        }
    }
}

можете его дополнить своим кодом до тех пор, пока он не начнёт ругаться на переполнение стека?
всю ночь не ем, весь день не сплю — устаю
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.