Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];
ВнизКак бы управлять порядком уничтожения компонентов? Найти похожие ветки
← →
PVOzerski © (2005-03-16 12:20) [0]Сейчас делаю наборчик компонентов, позволяющих работать с некой локальной БД из нескольких потоков. Сделал компонент-сервер и подключающийся к нему компонент-клиент (наследник tDataSet со свойством Server). При этом клиентов у одного сервера может быть несколько.
В нынешнем варианте компоненты кладутся на форму, таким образом она и оказывается их Owner"ом. И из-за этого возникает проблема. А именно: при уничтожении формы она уничтожает компоненты в "своем" порядке и может уничтожить серверный раньше его клиентов, которые не успеют сделать, условно говоря, "прощальные" закрытия.
Первое, что хотелось сделать, - динамически переназначать Owner"а серверу с формы на компоненты-клиенты at run-time. По рассмотрении кода components.pas, стало ясно, что штатным образом это не сделать. Какие-нибудь идеи есть?
← →
TUser © (2005-03-16 12:25) [1]Первая мысль - в OnClose формы уничтожить все компоненты в правильном порядке.
← →
VMcL © (2005-03-16 12:28) [2]>>PVOzerski © (16.03.05 12:20)
Исходный текст компонента-сервера доступен? Если, да, то я бы сделал по-другому. Не бросал "клиентов" на форму, а с помощью дизайнера, определял бы в дизайн-тайме, как коллекцию клиентов компонента-сервера. Что-то вроде того, как сделано с колоноками TListView.
?
← →
Erik1 © (2005-03-16 12:30) [3]Есть например при уничтожении сервера ты можеш затребовать уведомнения об этом. procedure Notification(AComponent: TComponent; Operation: TOperation); Установить это можно так:
procedure TAttribHolder.SetNotification;
var
I: Integer;
Component: TComponent;
begin
for I := fAttribute.Count - 1 downto 0 do begin
Component := TComponent(fAttribute[i].fComps);
if Component <> nil then Component.FreeNotification(Self);
end;
end;
И сделай все прощальные закрытия.
← →
VMcL © (2005-03-16 12:30) [4]>> [2]
Велик и могучая русский языка.
Исходный текст компонента-сервера доступен? Если, да, то я бы сделал по-другому. Не бросал "клиентов" на форму, а с помощью дизайнера, настраивал бы в их дизайн-тайме, как коллекцию клиентов компонента-сервера. Что-то вроде того, как сделано с колонками TListView.
?
← →
PVOzerski © (2005-03-16 12:42) [5]2TUser © (16.03.05 12:25) [1]
Нет, это не совсем то. Задача не как использовать в проекте "что есть", а как эти компоненты сами удачнее реализовать.
2VMcL © (16.03.05 12:28) [2]:
А потом такие клиенты назначать DataSet"ами всяким DB aware-контролам в design-time получится? Проверять долго :(
← →
Набережных С. © (2005-03-16 12:54) [6]Смотри Erik1 © (16.03.05 12:30) [3]. Механизм нотификации уже существует, достаточно в клиенте обрабатывать уведомления, и если уничтожается сервер, то закрывать соединение. Ну и регистрироваться, на случай размещения сервера и клиента в разных контейнерах. Если стандартный чем-то не устраивает - создай подобный свой.
← →
PVOzerski © (2005-03-16 12:55) [7]Есть у меня еще идейка... Если получится, расскажу :)
← →
Набережных С. © (2005-03-16 13:15) [8]Нотификацию по-любому обрабатывать придется, чтобы в клиенте обнулить ссылку на сервер. Зачем лишнее делать?
← →
Anatoly Podgoretsky © (2005-03-16 13:35) [9]Component1.Free;
Component2.Free;
...
ComponentN.Free;
← →
icWasya © (2005-03-16 13:47) [10]а про FreeNotification забыли ??
← →
PVOzerski © (2005-03-16 16:38) [11]В общем, задачу решил так. "Серверный" компонент теперь занимается серверными делами не сам, а из порождает экземпляр "настоящего серверного" класса, не имеющего Owner"a, зато имеющего счетчик подключенных клиентов. Как только счетчик обнуляется, вызывается деструктор. А чтобы он не уничтожился, если все клиенты отключились временно, одним из клиентов регистрируется сам "серверный" компонент, породивший этот экземпляр.
← →
Набережных С. © (2005-03-16 18:08) [12]Ну то есть программист, использующий твой компонент, напишет в коде Server.Free и будет свято верить, что прихлопнул соединение(и это, имхо, логично). А на самом деле соединение будет продолжать существовать. Свежий подход:) Дело, конечно, твое, но мне вот не понятно - на кой ляд? Уже существует стандартный механизм нотификации, ничего не надо делать. Просто перекрыть у клиента метод Notification, а при назначении/обнулении его свойства Server вызывать соответственно FreeNotification/RemoveFreeNotification сервера, в случае, если клиент и сервер находятся в разных контейнерах. Все, получаем нормальное, привычное и логичное поведение без всяких дополнительных объектов и списков.
← →
Димон (2005-03-16 18:19) [13]я бы тоже пользовался notification.
← →
MalkoLinge © (2005-03-16 19:36) [14]ИМХО
1.Нотификация об уничтожении сервера для обнуления ссылок клиентов.
2. Побочным эффектом свойства Server для компонента клиента сделать безопасное отключение клиента от сервера.
И не надо никаких счетчиков ссылок и объектов без владельцев. Ибо 1. не решит это проблемы , как было замечно выше, явного прибития серверного объекта.
2. Не решит проблемы некорректного отключения клиента от сервера (нормально не решит).
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.03.27;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.042 c