Здравствуйте, visus, Вы писали:
TK>>Автор случайно не Григорий Остер?
V>Минус решил не ставить. RTFM.
А мне вот что-то очень хочется тебе минус поставить.
Ecma-334 (C# Language Specification):
17.12 Finalizers
[Note: In the previous version of this standard, what is now referred to as a "finalizer" was called a
"destructor". Experience has shown that the term "destructor" caused confusion and often resulted to
incorrect expectations, especially to programmers knowing C++. In C++, a destructor is called in a
determinate manner, whereas, in C#, a finalizer is not. To get determinate behavior from C#, one should use
Dispose. end note]
Re[8]: В каком случае деструктор вызывается несколько раз?
PM>Во-вторых, мне кажется GetEncoding(1251) может давать немного не то, что Вы ожидаете, но я не до конца силен в кодировках, поэтому и говорю попробовать стандартную. Вы понимаете, что метдом проб и ошибок некоторые вещи должны решаться.
Код соответствует MSDN, файл пишется в нужной кодировке. Описание GetEncoding(1251) можете посмотреть сами.
> Про using я Вам дал ссылку, хотя достаточно было одного упоминания слова, чтобы Вы сами поискали. Читаете по-английски? Тогда возьмите и почитайте. А еще к этому почитайте какую-нибудь книгу по платформе и языку, допустим Рихтер, Петцольд, можно даже Троелсена, Нэш... Такие вопросы базовые отпадут одномоментно.
Прочитайте пожалуйста ветку с начала. Я не искал ничего про using, вы сами себя ввели в заблуждение. И то, что вы не знали про существование "Destructors" в понимании C#, говорит о том, что вы не совсем владеете темой вопроса.
>> всё должно работать.
PM>Работает?
Работает. Вас это беспокоит? Вы хотите об это поговорить? Я в общем-то не против.
Re[5]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
TK>>Автор случайно не Григорий Остер? V>Минус решил не ставить. RTFM.
Старайтесь просто меньше концентрироваться на чтении FM и больше на понимании. тема "деструкторы в C#" поднималась тут уже не раз — в классическом понимании деструкторов в c# нет и если вы не хотите создать "недопонимание" то, использовать это сло надо очень осторожно.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[11]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
V>За собой я оставляю право использовать термины деструктор и конструктор как методы, вызываемые в момент создания или уничтожения объекта.
Вы пишете в форум, я сделал пару предположений, заодно заметил про корявое использование IDisposable объектов ( не зря говорят "добрыми делами вымощена дорога в ад"). Это раз.
Да, используйте как хотите, но не ждите понимания от окружающих. И кто еще фельдшер.
--------------------------
less think — do more
Re: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
V>Что же это получается? Вызов деструктора неопределен не только по времени, но и по количеству? У меня на один вызов конструктора COM объекта по 300 вызовов деструктора. Я в панике
В .Net Framework нет деструктора. Есть финалайзер и IDisposable.Dispose, оба могут быть вызваны много раз.
В COM нет деструтора, есть IUnknown.Release. Должен быть вызван столько же раз, сколько IUnknown.AddRef, то есть, может быть вызван много раз.
Здравствуйте, visus, Вы писали:
V>>>Прочитайте пожалуйста ветку с начала. Я не искал ничего про using, вы сами себя ввели в заблуждение. И то, что вы не знали про существование "Destructors" в понимании C#, говорит о том, что вы не совсем владеете темой вопроса.
V>Павел, вы пичкаете меня ссылками с упорством деревенского фельдшера и даже не потрудились спросить меня, а знаю ли я что такое finalizer, using, dispose, сборщик мусора и т.п. (уже перечислял). Я вас
А что, должны спрашивать? Судя по корявому коду... И по испытваемым фрустрациям на тему "что вы тут мне говорите, да я и так знаю"... Ну раз все знаешь, зачем спрашиваешь?
В каком случае деструктор вызывается несколько раз?
Что же это получается? Вызов деструктора неопределен не только по времени, но и по количеству? У меня на один вызов конструктора COM объекта по 300 вызовов деструктора. Я в панике
Re[2]: В каком случае деструктор вызывается несколько раз?
D>Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.
Было бы чего показывать:
[ComVisible(true)]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("PSM.Folder")]
[Guid("43933A80-32DF-436c-8296-FF16B4A32A01")]
public class SomeObject
...
Здравствуйте, visus, Вы писали:
D>>Все местные телепаты сейчас на выходных и в отпусках. Так что не паникуйте, а показывайте код.
V>Было бы чего показывать:
V>Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.
На указанных местах вылетает StackOverflow? А Вы пробовали с другой кодировкой писать, например Encoding.Unicode?
Что в файлах?
И почитайте про using
--------------------------
less think — do more
Re[4]: В каком случае деструктор вызывается несколько раз?
V>>Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.
PM>На указанных местах вылетает StackOverflow? А Вы пробовали с другой кодировкой писать, например Encoding.Unicode? PM>Что в файлах?
Это простая тестовая программа. Когда я её запускал под отладкой, то в некоторых случаях возникал StackOverflow на указанной строке. Воспроизводить не удается. Пока идей нет. Нет, unicode не пробовал.
PM>И почитайте про using
Вот тут подробнее пожалуйста. Где в данном коде нужен using? Я не вижу тут места для его применения.
Re[5]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
V>>>Этот код — результат попытки понять, почему программа падает при созданиии нескольких простых объектов.
PM>>На указанных местах вылетает StackOverflow? А Вы пробовали с другой кодировкой писать, например Encoding.Unicode? PM>>Что в файлах?
V>Это простая тестовая программа. Когда я её запускал под отладкой, то в некоторых случаях возникал StackOverflow на указанной строке. Воспроизводить не удается. Пока идей нет. Нет, 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]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, TK, Вы писали:
TK>Здравствуйте, visus, Вы писали:
A>>>О чём речь вообще? V>>Вот об этом: Destructors (C# Programming Guide)
TK>Автор случайно не Григорий Остер?
Я не вижу как ваши ответы могут соотноситься с сутью вопроса.
Что может быть не так с codepage 1251? В вашей практике были какие-то примеры?
Про using я поторяю вопрос: приведите пример, как бы вы в указанном коде использовали using?
Коллеги, я прошу серьезнее отнестись к вопросу.
По поводу множественных вызовов деструктора у меня есть поверхностное предположение: возможно, если в деструкторе возникает исключение, то машинка считает финализацию объекта незавершенной и оставляет в очереди. Но в данном коде исключению взяться неоткуда, всё должно работать. И результат работы этого кода я вижу в файле. FW 2.0
Re[5]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, 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 отсутствует. Удаление объекта происходит в недетерминированный момент времени, соответственно нет служебного метода, вызываемого при удалении момента в детерминированный момент времени.
Здравствуйте, 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]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, Pavel M., Вы писали:
A>Деструктор, в понимании Си++ в .Net отсутствует. Удаление объекта происходит в недетерминированный момент времени, соответственно нет служебного метода, вызываемого при удалении момента в детерминированный момент времени.
Да что Вы мне-то это рассказывайте, я это прекрасно знаю. Просто думал, что это они же ввели понятие "финализатор" и порекомендовали не употреблять "деструктор", этому и удивляюсь)
--------------------------
less think — do more
Re[7]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
V>Я не вижу как ваши ответы могут соотноситься с сутью вопроса. V>Что может быть не так с codepage 1251? В вашей практике были какие-то примеры? V>Про using я поторяю вопрос: приведите пример, как бы вы в указанном коде использовали using? V>Коллеги, я прошу серьезнее отнестись к вопросу. V>По поводу множественных вызовов деструктора у меня есть поверхностное предположение: возможно, если в деструкторе возникает исключение, то машинка считает финализацию объекта незавершенной и оставляет в очереди. Но в данном коде исключению взяться неоткуда, всё должно работать. И результат работы этого кода я вижу в файле. FW 2.0
Во-первых, сейчас суббота и я вобще удивлен, что кто-то не отдыхает)
Во-вторых, мне кажется GetEncoding(1251) может давать немного не то, что Вы ожидаете, но я не до конца силен в кодировках, поэтому и говорю попробовать стандартную. Вы понимаете, что метдом проб и ошибок некоторые вещи должны решаться. Про using я Вам дал ссылку, хотя достаточно было одного упоминания слова, чтобы Вы сами поискали. Читаете по-английски? Тогда возьмите и почитайте. А еще к этому почитайте какую-нибудь книгу по платформе и языку, допустим Рихтер, Петцольд, можно даже Троелсена, Нэш... Такие вопросы базовые отпадут одномоментно.
> всё должно работать.
Работает?
--------------------------
less think — do more
Re[6]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, 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". Дальше не менее чётко написано, что код деструктора транслируется в следующее:
Если же Вы попробуете явно перекрыть Finalize(), то получите ошибку от компилятора "напишите вместо Finalize() деструктор".
A>Деструктор, в понимании Си++ в .Net отсутствует. Удаление объекта происходит в недетерминированный момент времени, соответственно нет служебного метода, вызываемого при удалении момента в детерминированный момент времени.
М-да-а-а... Ну и каша в головах... Зачем нам метод для детерминированного момента, ежели удаляем в недетерминированный ??? Всё так же как в C++: когда реально удаляем, тогда и вызываем служебный метод.
Ключевое свойство деструкторов вовсе не детерминированность какого-то там момента, а то что они вызываются runtime'ом вне нормального контекста исполнения кода. Что, по-совместительству, и является их основной проблемой.
Re[7]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, drol, Вы писали:
D>Дальше не менее чётко написано, что код деструктора транслируется в следующее:
Следующее как раз финалайзер и есть.
D>М-да-а-а... Ну и каша в головах... Зачем нам метод для детерминированного момента, ежели удаляем в недетерминированный ??? Всё так же как в C++: когда реально удаляем, тогда и вызываем служебный метод.
Забавно, и это у меня каша. Метод нужен, почитай про IDisposable. Просто в отличие от Си++, его приходится выхывать вручную.
D>Ключевое свойство деструкторов вовсе не детерминированность какого-то там момента, а то что они вызываются runtime'ом вне нормального контекста исполнения кода. Что, по-совместительству, и является их основной проблемой.
Это свойство финалайзеров, в рантайме никаких деструкторов нет.
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);
}
}
}
}
}
}
можете его дополнить своим кодом до тех пор, пока он не начнёт ругаться на переполнение стека?
всю ночь не ем, весь день не сплю — устаю
Re[4]: В каком случае деструктор вызывается несколько раз?
V>StreamWriter sw = new StreamWriter(file, enc1251); // Why stack overflow?
[/c#]
_FR>Call Stack в точке возникновения "stack overflow" давай посмотрим.
Сейчас stack overflow возникает в недрах mscorlib.dll с вероятностью 25-30% при создании экземпляра объекта. Это при том, что все методы закомментированы.
Re[4]: В каком случае деструктор вызывается несколько раз?
Только у меня dll и framework 2.0. В новом проекте работает. Но уже понятно, что проблема не в этом коде, а в окружении объекта. В глючном проекте даже "чистый" объект без методов дает stack overflow.
Постараюсь сегодня локализовать проблему путем последователеьной реконструкции глючного проекта в отдельном проекте.
Re[8]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, adontz, Вы писали:
A>Следующее как раз финалайзер и есть.
Finalizer — терминология CLI. Спецификация же C#, как можно видеть, использует термин деструктор. И слово finalizer в ней можно найти только в названиях методов.
A>Забавно, и это у меня каша.
Конечно. Ведь чтобы каши не было, нужно, как минимум, читать спецификации.
A>Метод нужен, почитай про IDisposable. Просто в отличие от Си++, его приходится выхывать вручную.
А типа на C++ аналог IDisposable с "ручным" вызовом сделать невозможно. "Гы" много раз...
Повторяю ещё раз: деструкторы (или finalizer'ы, если Вам больше нравится терминология CLI) вызываются runtime'ом вне нормального контекста исполнения. Тогда как IDisposable.Dispose() вызывается совершенно обычным способом, и в нормальном контексте исполнения.
Re[9]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, drol, Вы писали:
D>Здравствуйте, adontz, Вы писали:
A>>Следующее как раз финалайзер и есть.
D>Finalizer — терминология CLI. Спецификация же C#, как можно видеть, использует термин деструктор. И слово finalizer в ней можно найти только в названиях методов.
A>>Забавно, и это у меня каша.
D>Конечно. Ведь чтобы каши не было, нужно, как минимум, читать спецификации.
A>>Метод нужен, почитай про IDisposable. Просто в отличие от Си++, его приходится выхывать вручную.
D>А типа на C++ аналог IDisposable с "ручным" вызовом сделать невозможно. "Гы" много раз...
D>Повторяю ещё раз: деструкторы (или finalizer'ы, если Вам больше нравится терминология CLI) вызываются runtime'ом вне нормального контекста исполнения. Тогда как IDisposable.Dispose() вызывается совершенно обычным способом, и в нормальном контексте исполнения.
А кто-то в этом сомневался? IDisposable раскрывается в try-finally блок.
--------------------------
less think — do more
Re[9]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
>>> всё должно работать.
PM>>Работает?
V>Работает. Вас это беспокоит? Вы хотите об это поговорить? Я в общем-то не против.
Поговорите тут сами с собой. Может быть от этого лучше заработает. Вы ошиблись форумом.
--------------------------
less think — do more
Re[9]: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
V>Прочитайте пожалуйста ветку с начала. Я не искал ничего про using, вы сами себя ввели в заблуждение. И то, что вы не знали про существование "Destructors" в понимании C#, говорит о том, что вы не совсем владеете темой вопроса.
Developer Guide — хорошая вещь, но книги признанные тоже являются официальными документами, которые ревьюируются не раз перед выходом.
Does the Object Need a Finalizer?
A finalizer is a method that you can implement on your class and that is called prior to the GC
cleaning up your unused object from the heap. Let’s get one important concept clear up front:
Finalizers are not destructors, nor should you view them as destructors.
Destructors are associated with deterministic destruction of objects. Finalizers are associated
with nondeterministic destruction of objects. Unfortunately, much of the confusion between finalizers
and destructors comes from the fact that the C# language designers chose to map finalizers
into the C# destructor syntax, which is identical to the C++ destructor syntax. In fact, you’ll find that
it’s impossible to overload Object.Finalize explicitly in C#. You overload it implicitly by using the
destructor syntax that you’re used to if you come from the C++ world. The only good thing that
comes from C# implementing finalizers this way is that you never have to worry about calling the
base class finalizer. The compiler does that for you.
Субудай показал пальцем на лохматую собачонку, которая жалась к ногам
охотника и огрызалась на монголов;
— Как по-урусутски зовется эта зверушка?
Охотник ответил:
— А пес! Пустобрех!
Субудай спросил другого:
— Как зовут зверушку?
— Жучка! Тютька!
Субудай спросил третьего охотника. Тот сказал:
— Лайка! Охотницкая собачонка.
Субудай покачал головой:
— Трудный язык урусутов. По-монгольски все просто и ясно — одно слово
"нохой", и все знают, что это собака. А урусуты — путаники. Каждый назы-
вает по-своему. Вот они и не понимают друг друга.
(С) В,Ян "Батый"
With best regards
Pavel Dvorkin
Re[4]: В каком случае деструктор вызывается несколько раз?
Re[4]: В каком случае деструктор вызывается несколько раз?
От: visus
Дата: 20.10.08 22:48
Так, похоже кидаться ссылками без каких-либо причин и обьяснений в этом форуме считается нормой.
Что такое деструктор, finalize, using, dispose, сборщик мусора я знаю. Мне твоя ссылка настолько же полезна как тебе вот эта: Смотри здесь
Re: В каком случае деструктор вызывается несколько раз?
Здравствуйте, visus, Вы писали:
V>Что же это получается? Вызов деструктора неопределен не только по времени, но и по количеству?
Без спецального участия объекта финалайзер будет вызван не более 1 раза. При желании можно сделать так, чтобы финалайзер вызывался сколь угодно много раз (resurrection)
V>У меня на один вызов конструктора COM объекта по 300 вызовов деструктора. Я в панике
Вы уверены, что COM-объект работает корректно?
... << RSDN@Home 1.2.0 alpha 4 rev. 1111>>
Re[10]: В каком случае деструктор вызывается несколько раз?
V>>Прочитайте пожалуйста ветку с начала. Я не искал ничего про using, вы сами себя ввели в заблуждение. И то, что вы не знали про существование "Destructors" в понимании C#, говорит о том, что вы не совсем владеете темой вопроса.
PM>Developer Guide — хорошая вещь, но книги признанные тоже являются официальными документами, которые ревьюируются не раз перед выходом.
PM> PM>Does the Object Need a Finalizer?
Павел, вы пичкаете меня ссылками с упорством деревенского фельдшера и даже не потрудились спросить меня, а знаю ли я что такое finalizer, using, dispose, сборщик мусора и т.п. (уже перечислял). Я вас прямо спрашивал, но вы не сочли за труд объяснить, зачем вы меня лечите. За ваше упорство награждаю вас заслуженной троечкой с минусом.
С радостью сниму троечку и даже готов извиниться за что-нибудь, если вы всё таки прислушаетесь к моей просьбе обосновать вашу позицию и пояснить, зачем же мне ваши ссылки для выяснения темы "В каком случае деструктор вызывается несколько раз?".
За собой я оставляю право использовать термины деструктор и конструктор как методы, вызываемые в момент создания или уничтожения объекта.
Re[2]: В каком случае деструктор вызывается несколько раз?
PM>Вы пишете в форум, я сделал пару предположений, заодно заметил про корявое использование IDisposable объектов ( не зря говорят "добрыми делами вымощена дорога в ад"). Это раз. PM>Да, используйте как хотите, но не ждите понимания от окружающих. И кто еще фельдшер.
Я очень рад, что наконец-то наметились тенденции к диалогу без лишних ссылок. Сразу перейду к делу: этот код вообще-то рабочим кодом не является и он работает, это очевидно и вы могли бы это заметить сразу. Зачем рабочему коду писать в файл сообщение о уничтожении объекта? Как бы я узнал, что деструктор вызывается 300 раз, если бы этот код не работал?
Изначально вы сделали три неверных предположения и не обращали внимания на мои уточняющие вопросы. Так что... минусики я уберу, а фельдшера оставлю В надежде, что в будущем вы будете внимательнее.