Re[6]: COM объект и Finalize
От: DragonFire Россия  
Дата: 18.07.09 14:10
Оценка:
Здравствуйте, Аноним, Вы писали:

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



А>>>Отсюда следует, что для Вашей задачи финализатор — место совсем не подходящее, надо искать другое. А вот порядком вызова Dispose мы вполне способны управлять. Вот я смотрю — Dispose формы вызывает Dispose всех своих компонентов. Почему-бы и Вашим сущностям не выполнить свои завершающие действия здесь-же, даже если они не являются компонентами. А если являются, то можно это сделать в их Dispose.


DF>>А вот тут как раз мы не можем предсказать что вызовется раньше — Dispose моей оболочки COM-объекта или Dispose таблицы, ссылающейся на эту оболочку. И тогда, опять же, может возникнуть ситуация когда таблица не сможет закрыться из-за завершенности соединения с COM.


А>Странно. Мне показалось, что это как раз легко предсказуемо Попробовал — получилось. Но видиммо, я что-то не так делал.


Тут когда как. Смотрите, есть форма и у нее такие поля:
MyTable t1;
MyCOMComponent c;
MyTable t2;

Создавая таблицы, я передаю им компонент, примерно так: t1 = new MyTable(c);
Теперь при закрытии формы каждая таблица должна выполнить нечто вроде c.Exec("Close Table t1.tab");
И может я ошибаюсь, но я не вижу гарантии что выполнится именно так программа:
t1.Dispose(); //c.Exec("Close Table t1.tab");
t2.Dispose(); //c.Exec("Close Table t2.tab");
c.Dispose(); //this.Exec("End Application");
А не так:
t1.Dispose(); //c.Exec("Close Table t1.tab");
c.Dispose(); //this.Exec("End Application");
t2.Dispose(); //Ошибка


А>Ну а зачем пользоваться чем-то, что безграмотно написано? Впрочем, я так понял, что Вы уже нашли решение в рамках своей парадигмы. Но делиться своим решением с кем-либо не желаете...Ну что-же, тоже позиция, в некотором смысле.

А>Желаю удачи.

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

А насчет пользоваться... Тут я с Вами полностью согласен, но приходиться, когда альтернативы нету...
Re[7]: COM объект и Finalize
От: Аноним  
Дата: 18.07.09 14:44
Оценка:
Здравствуйте, DragonFire, Вы писали:

DF>Здравствуйте, Аноним, Вы писали:


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



А>>>>Отсюда следует, что для Вашей задачи финализатор — место совсем не подходящее, надо искать другое. А вот порядком вызова Dispose мы вполне способны управлять. Вот я смотрю — Dispose формы вызывает Dispose всех своих компонентов. Почему-бы и Вашим сущностям не выполнить свои завершающие действия здесь-же, даже если они не являются компонентами. А если являются, то можно это сделать в их Dispose.


DF>>>А вот тут как раз мы не можем предсказать что вызовется раньше — Dispose моей оболочки COM-объекта или Dispose таблицы, ссылающейся на эту оболочку. И тогда, опять же, может возникнуть ситуация когда таблица не сможет закрыться из-за завершенности соединения с COM.


А>>Странно. Мне показалось, что это как раз легко предсказуемо Попробовал — получилось. Но видиммо, я что-то не так делал.


DF>Тут когда как. Смотрите, есть форма и у нее такие поля:

DF>MyTable t1;
DF>MyCOMComponent c;
DF>MyTable t2;

DF>Создавая таблицы, я передаю им компонент, примерно так: t1 = new MyTable(c);

DF>Теперь при закрытии формы каждая таблица должна выполнить нечто вроде c.Exec("Close Table t1.tab");
DF>И может я ошибаюсь, но я не вижу гарантии что выполнится именно так программа:
DF>t1.Dispose(); //c.Exec("Close Table t1.tab");
DF>t2.Dispose(); //c.Exec("Close Table t2.tab");
DF>c.Dispose(); //this.Exec("End Application");
DF>А не так:
DF>t1.Dispose(); //c.Exec("Close Table t1.tab");
DF>c.Dispose(); //this.Exec("End Application");
DF>t2.Dispose(); //Ошибка

Ну почему?! Вы же в методе шызщыу ормы вольны сами задать порядок вызова.
Возможно, моё предложение навеяно нативом, и не совсем подходяще для NET, но я бы сделал так — коль скоро пользователи Вашего враппера написаны Вами-же, то пусть они в конструкторе добавляют себя в список "корреспондентов" Вашего враппера. Тогда этот враппер в своём Dispose сможет вызвать Dispose всех своих актуальных корреспондентов, ну а необходимость вызова Dispose для самого враппера уже подразумевается реализацией им IDisposable, а кто этого не сделает, тот Сам Себе Злобный Буратино. По-моему, всё равно более жёстко это обусловить невозможно, и если я не прав, то пусть более опытные в NET товарищи меня поправят. Это подразумевает, что пользователи Вашего враппера должны иметь флаг disposed, для нейтрализации попыток многократного вызова этого метода, но это, как я понял, нормально для NET. Впрочем, при желании для этого можно задействоовать и какое-нибудь nullable поле, хотя вряд-ли оно того стоит.

DF>В отпуск на неделю ухожу


Блин, отпуск — это хорошо, но неделя — это просто издевательство Не, я где-нибудь в середине или начале августа, по погоде, и — на месяц! Завалюсь в тайгу к другу и телефон выключу, всё одно там не примет!!!
Re[8]: COM объект и Finalize
От: DragonFire Россия  
Дата: 18.07.09 16:23
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Ну почему?! Вы же в методе шызщыу ормы вольны сами задать порядок вызова.

А>Возможно, моё предложение навеяно нативом, и не совсем подходяще для NET, но я бы сделал так — коль скоро пользователи Вашего враппера написаны Вами-же, то пусть они в конструкторе добавляют себя в список "корреспондентов" Вашего враппера. Тогда этот враппер в своём Dispose сможет вызвать Dispose всех своих актуальных корреспондентов, ну а необходимость вызова Dispose для самого враппера уже подразумевается реализацией им IDisposable, а кто этого не сделает, тот Сам Себе Злобный Буратино. По-моему, всё равно более жёстко это обусловить невозможно, и если я не прав, то пусть более опытные в NET товарищи меня поправят. Это подразумевает, что пользователи Вашего враппера должны иметь флаг disposed, для нейтрализации попыток многократного вызова этого метода, но это, как я понял, нормально для NET. Впрочем, при желании для этого можно задействоовать и какое-нибудь nullable поле, хотя вряд-ли оно того стоит.

Да, вариант хорош... Через неделю попробую реализовать его и не связываться со сборщиком мусора...

А>Блин, отпуск — это хорошо, но неделя — это просто издевательство Не, я где-нибудь в середине или начале августа, по погоде, и — на месяц! Завалюсь в тайгу к другу и телефон выключу, всё одно там не примет!!!


Да я бы тоже уехал, да у нас студентов, лето — возможность поработать в два раза больше чем зимой
Неделя мало конечно, зато вообще никакой работы, как ты верно сказал — мобильник выключить
Re[9]: COM объект и Finalize
От: DragonFire Россия  
Дата: 06.08.09 20:52
Оценка:
Если кому-нибудь будет интересно — реализовал через Dispose и непосредственный вызов его при закрытии формы...
Если чего-нибудь новое придумаю, отпишу тут...
Re: COM объект и Finalize
От: servancho Россия https://dedis.ru
Дата: 06.08.09 21:53
Оценка:
Здравствуйте, DragonFire, Вы писали:

DF>День добрый всем.


Мы на эти грабли наступили когда тесты писали под MSный тест-фреймворк. Проблема получила кодовое название "отслоение сетчатки COM-объекта"
Лечили следующим образом. Т.к. в проблеммном коде COM-объект создается и финализируется на разных тредах, гарантируем его создание на MTAшном треде (после тред можно не держать, главное чтоб инстанс КОМ-объекта был на нем создан), после всего в диспозе все что нужно объекту сообщаем и ему дергаем диспоз чтобы финализатор GC не вызывался. Нам помогло.
Если руки золотые, не важно из какого места они растут.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.