|
почему IInitDone.Done вызывается лишь при закрытии 1с | ☑ | ||
---|---|---|---|---|
0
victor79
01.12.12
✎
18:31
|
в процедуру Done запихнул DoMessageBox, и наблюдаю, что все созданные объекты уничтожаются по закрытию всей 1с, а не обработки в которой создвались. Если бы были проблемы с количеством ссылок, то 1с вообще бы зависала в процессах, а этого нету.
|
|||
1
Aleksey
01.12.12
✎
18:35
|
тогда объекты уничтожались бы в процедуры ПриНачалеРаботыСистемы. Т.е. при первичной инициализации.
Короче я против |
|||
2
Нуф-Нуф
01.12.12
✎
18:37
|
вы о чем ваще?
|
|||
3
H A D G E H O G s
01.12.12
✎
18:45
|
Если бы были проблемы с количеством ссылок, то 1с вообще бы зависала в процессах, а этого нету.
Не факт. |
|||
4
H A D G E H O G s
01.12.12
✎
18:46
|
Если это на Дельфи, на основе ВК от Ромикса, то там есть досадная ошибка.
|
|||
5
orefkov
01.12.12
✎
23:28
|
Тут не надо думать "почему". Надо принять это как есть, ну и как-то жить с этим.
|
|||
6
victor79
02.12.12
✎
02:14
|
(4) на дельфи, на основе шаблонов с древнего ИТС. Без запроса AppDispatch, и как следствие без _AddRef который был нужен в семерке.
(5) Принять как есть сложно, т.к. если вдруг буду хранить большие объемы данных в ВК, то будет досадное растранжиривание памяти. |
|||
7
victor79
08.12.12
✎
07:38
|
up
|
|||
8
Torquader
08.12.12
✎
15:16
|
В 1С были и другие проколы, когда созданная переменная не очищалась и хранила своё значение до закрытия 1С.
Кроме того, когда загружается внешняя компонента, то она живёт в системе независимо от того, создавались ли из неё объекты или нет, так как создание объекта происходит после загрузки компоненты. Да и по логике действий понятно, что если компонента нужна, то её загружают только один раз - так проще, чем отслеживать необходимость и счётчики использования компоненты - если бы была команда, подобная UseModule, чтобы указать, какие модули используются в коде - тогда бы был динамический загрузчик - а так - он только статический - раз и всё. |
|||
9
vde69
08.12.12
✎
15:37
|
сталкивался, в результате перешел на техологию НАВИТЕ, вроде лучше...
единственное конечно нужно явно ресы освобюождать пример в личке |
|||
10
Рэйв
08.12.12
✎
15:48
|
(0)MDI интерфэйс - слыхал о таком?
Пока родительское окно не закроешь- все живет |
|||
11
vde69
08.12.12
✎
16:36
|
(10) при чем тут MDI ??? ВК вообще то отдельным процессом запускается и в нем вообще не обязательно есть визуальные обьекты...
Есть дискриптор процесса и вот он не закрывается, почему - хз... Хотя в теории должен. |
|||
12
Torquader
08.12.12
✎
17:10
|
Позвольте - VB - это dll, она просто подгружается в память - и живёт там, пока явно не будет вызвана функция выгрузки dll, а в 1С есть выгрузка внешней компоненты ?
|
|||
13
Рэйв
08.12.12
✎
17:16
|
(11)Процесс то внутр чего запускается? Внутри 1С.Вызов компаненты там же..
Так что (10) |
|||
14
Рэйв
08.12.12
✎
17:18
|
и дело даже не в родительском окне, а в экземпляре приложения
|
|||
15
Torquader
08.12.12
✎
17:20
|
(13) Начнём с того, что окна и очередь привязаны к потоку в процессе, а dll подключаются ко всем потокам сразу, так как адресное пространство едино.
Потом, 1С запрашивает таблицу расширений - если она её запросила, что счётчик dll увеличился, а отдать назад таблицу она уже не может, независимо от того, что закрылась обработка - интерпретатор, то общий. Ну, конечно, могут быть другие потоки, но они часто обслуживают только всплывающие подсказки и окна выбора файлов - так в винде повелось, что всплывают подсказки в другом потоке. |
|||
16
Рэйв
08.12.12
✎
17:25
|
(15)Ну окна не к потоку допустим привязаны:-) Ну ладно, не будем тут хрень разводить
|
|||
17
Torquader
08.12.12
✎
17:29
|
(16) Очередь сообщений у каждого потока своя - окно может быть привязано только к одной очереди сообщений - ну дальше надо ?
|
|||
18
Рэйв
08.12.12
✎
17:30
|
(15)А вообще - с точки зрения банальной эрудиции- каждый идивидуум не может отрицать теорию утопической субъективности.
И поэтому цинизм твоих доводов асациируется с мистикой парадоксальных иллюзий. |
|||
19
Рэйв
08.12.12
✎
17:33
|
(17)еще как нажл:-).. Поток - эт таймер - ии таймеров на форме может быть огого- скока
|
|||
20
Рэйв
08.12.12
✎
17:33
|
нажл = надо
|
|||
21
vde69
08.12.12
✎
17:33
|
(13)(15) есть раннее и позднее связываение, длл загружается в адресное пространство 1с только при раннем связыванием, по факту все типовые ВК - используют механизм позднего связывания и работают в отдельном потоке и отдельном адресном пространстве, без использования процедур работы с глобальной памятью оба потока связаны только через интерфейсную структуру (где описываются адреса вызовов) и дескритор, и все...
по поводу совместного использования одной длл несколькими приложениями и вытекающими от сюда проблеммами, тут определенная правда есть, но лично я не уверен что это как-то связано. |
|||
22
Torquader
08.12.12
✎
17:44
|
(21) В 32 и 64 системах у каждого процесса своё адресное пространство и нет возможности использовать dll несколькими процессами сразу, если она не заявлена как системная и под неё не выделено общее для всех процессов адресное пространство.
Что касается связывания, то inprocess-объекты спокойно живут в одном потоке с родителем, так как управление передаётся им только на момент вызова метода. (19) Поток - это не таймер - это стек исполнения. К сожалению, 1С не поддерживает параллельное исполнение кода - поэтому основной поток у неё только один. |
|||
23
Рэйв
08.12.12
✎
17:49
|
(22)Я сожалею о том, что 1С не поддерживает параллельные вычисления вместе с тобой.
Но не будем углубляться до машинных кодов, я умоляю!:-) Таймер - это поток и с ним работают на среднем уровне програмеры:-) Средний-- в смысле доступа к данным.. Ну ты понимаешь, надеюсь.:-) |
|||
24
Torquader
08.12.12
✎
17:49
|
(21)+ ещё нужно понимать, что связывание часто соотносят с объектами и интерфейсами, а dll-это просто куски кода и данных (бывают dll только с картинами или строками, как например транслятор языка клавиатуры, где только таблицы раскладок).
Можно создать потокобезопасный объект, который будет обрабатывать вызовы сразу от нескольких потоков. При этом, возможны две ситуации для inproccess-вызовов (в пределах одного процесса) - или напрямую, когда мы вызываем саму функцию из dll или через посредника размещения - то есть вызывается функция в другом потоке через передачу данных по интерфейсу Imarshal и вызов удалённой процедуры. Между процессами работа возможна только через посредника. Собственно говоря, в этом и кардинальное отличие OLE-объектов в dll от просто dll - OLE-объект может быть создан один на все процессы и жить в каком-то одном, а обычная dll будет пристыкована только к одному процессу. Печальность ситуации с OLE-объектами в том, что они погибают при завершении основного процесса, и остальные процессы остаются без объектов и без данных. |
|||
25
Torquader
08.12.12
✎
17:51
|
(23) Таймер - это не поток - это событие.
Соответственно, поток может обслуживать таймеры, но это не значит, что каждый таймер живёт в отдельном потоке. В Windows система прекрасно обслуживает таймеры через очередь сообщений и в одном потоке. |
|||
26
orefkov
08.12.12
✎
17:51
|
(0)
Вообще-то оно и должно один раз вызыватся, при завершении работы. Считай ссылки на свои объекты. В конструктор и деструктор своего объекта вставь месадж бокс, узнаешь много нового. |
|||
27
Рэйв
08.12.12
✎
17:52
|
(25) Тебе не кажется, , что ты начинаешь буквоедствовать из принципа ?:-)
|
|||
28
Рэйв
08.12.12
✎
17:53
|
да, таймер - это сообщение виндов.И что?:-)..Вглубь полезем?
|
|||
29
Torquader
08.12.12
✎
17:54
|
(25)+ вот две функции - у них мало чего есть общего.
UINT SetTimer( HWND hWnd, // handle of window for timer messages UINT nIDEvent, // timer identifier UINT uElapse, // time-out value TIMERPROC lpTimerFunc // address of timer procedure ); HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to security attributes DWORD dwStackSize, // initial thread stack size LPTHREAD_START_ROUTINE lpStartAddress, // pointer to thread function LPVOID lpParameter, // argument for new thread DWORD dwCreationFlags, // creation flags LPDWORD lpThreadId // pointer to receive thread ID ); (27) Просто я больше пишу на Си и Ассемблере, чем на 1С, и у меня как раз программы работают в нескольких потоках - и я знаю, что бывает если процессы реально параллельно выполняются. |
|||
30
vde69
08.12.12
✎
17:54
|
(26) у меня деструктор вообще не вызывался.... по чему я так и не понял...
|
|||
31
Рэйв
08.12.12
✎
17:55
|
(29)Если ты заметил, это не я с тобой спорю, а ты со мной:).я то с тобой почти согласен:-)
|
|||
32
Рэйв
08.12.12
✎
17:56
|
(30)Если на фреймворке, то не печалься...Со временем подберет
|
|||
33
Torquader
08.12.12
✎
18:00
|
(32) Кстати да - если создаётся OLE-объект, то его система разрушает спустя какое-то время после освобождения последней ссылки - так сказать, его берегут какое-то время, если он опять понадобится.
Ещё есть проблема, когда объекты нечаянно сохраняют ссылки на себя или друг на друга - тогда они не освобождаются, пока не завершится процесс. Точнее сказать, они и не освобождаются по завершении процесса, просто dll принудительно выгружается из памяти по завершению, и на этом этапе уже мало кого интересует, что кто-то ещё не готов. Есть такая функция DllCanUnloadNow - полезно перехватывать её вызовы и смотреть, когда система спрашивает dll "а не пора ли ей домой". |
|||
34
Рэйв
08.12.12
✎
18:02
|
(33)Да нет.Все проще.
Сборщик "мусора" у фреймворка работает не стразу, вот и все |
|||
35
Рэйв
08.12.12
✎
18:02
|
*сразу
|
|||
36
Torquader
08.12.12
✎
18:04
|
Я просто сейчас посмотрел описание DllCanUnloadNow - там написано, что её должен реализовывать программист сам - если её нет, то dll будет выгружаться по завершении.
И сразу возникает вопрос - а у 1С компоненты кто-нить эту функцию реализовывал ? |
|||
37
Рэйв
08.12.12
✎
18:06
|
(36)Ты как первый раз замужем:-)
Нииразу не видел композиций void Noname() { // TO DO Something.... или чтото вроде:) } |
|||
38
Torquader
08.12.12
✎
18:08
|
(37) Я вот именно об этом и говорю, что если функцию "реализовали" именно так, то потом удивление, что dll не выгружается неуместно.
|
|||
39
Рэйв
08.12.12
✎
18:09
|
(38)У компонент для 1С определенный интерфейс. Ем унадо следовать если хочешь чтобы работало
|
|||
40
Рэйв
08.12.12
✎
18:10
|
можешь делать заглушки, но быт они должны
|
|||
41
Рэйв
08.12.12
✎
18:10
|
*быть
|
|||
42
Torquader
08.12.12
✎
18:10
|
(39) Интерфейс компонент понятен, но это более высокий уровень - там же тоже есть ссылки на объекты и счётчик использования, который как раз и используется для расчёта ответа на вызов.
|
|||
43
Рэйв
08.12.12
✎
18:11
|
(42)И что там для тебя не так?
|
|||
44
Torquader
08.12.12
✎
18:12
|
(40) Я говорю о том, что есть подозрение, что шаблон компоненты не использует счётчиков объектов, соответственно, не использует и запрос освобождения.
|
|||
45
Рэйв
08.12.12
✎
18:13
|
(44)Ты имеешь в виду, что можно 50 экземпяров ВК запустить? :-)
|
|||
46
Рэйв
08.12.12
✎
18:13
|
Ну я не пробовал..Даже спорить не буду
|
|||
47
Torquader
08.12.12
✎
18:13
|
Я тут вспомнил про (0) ещё вот что:
При открытии обработки нужно не забыть сбросить переменную в которой содержалась на неё ссылка, так как иначе обработка действительно остаётся в памяти - причём вся. |
|||
48
Torquader
08.12.12
✎
18:14
|
(45) Можно сколько угодно, только запуск следующих экземпляров ничего не будет делать - только увеличивать какие-то внутренние счётчики.
|
|||
49
Рэйв
08.12.12
✎
18:14
|
(47)В кеш пишется. А там все сложно...
|
|||
50
Рэйв
08.12.12
✎
18:16
|
(48)Не гони:-)..
|
|||
51
Рэйв
08.12.12
✎
18:16
|
(48) Любой студент знает как оставить в памяти ТОЛЬКО одно приложение
|
|||
52
Рэйв
08.12.12
✎
18:17
|
static
Параметр И все |
|||
53
Torquader
08.12.12
✎
18:17
|
(50) Так мы о чём говорим - о самой компоненте (то есть dll и вызове LoadLibrary) или об объектах компоненты, которые есть однопоточные Ole-объекты и на каждый вызов создания создаётся новый ?
|
|||
54
Рэйв
08.12.12
✎
18:18
|
(53)см (52)
|
|||
55
Torquader
08.12.12
✎
18:18
|
(51) Так приложение или объект ?
Приложение - это обычно отдельный процесс и там нужно через объекты взаимного исполнения отслеживать запуск. |
|||
56
Рэйв
08.12.12
✎
18:20
|
(55)Слушай, ...Вот ты буквоед.
Ничего что приложение - это тоже объект? Ничего, что в идеологии программирования современного -ВСЕ объекты? |
|||
57
Torquader
08.12.12
✎
18:20
|
На самом деле IClassFactory->CreateInstance - что в реализации напишешь, то и будет.
Можно вообще не создавать объекта, а только интерфейсную заглушку, чтобы реализовывала методы. |
|||
58
Рэйв
08.12.12
✎
18:20
|
Может мы еще о классах С++ пооворим?
|
|||
59
Рэйв
08.12.12
✎
18:21
|
Хорошо.
что тебе говорит IClassFactory->CreateInstance |
|||
60
Torquader
08.12.12
✎
18:21
|
Ладно успокойся, просто лучше называть понятия своими именами.
|
|||
61
Рэйв
08.12.12
✎
18:22
|
(59)Да я то спокоен:-)...Но у меня к тебе вопрос
|
|||
62
Torquader
08.12.12
✎
18:22
|
(59) Это функция, которая запрашивает создание объекта по определённому номеру в системе (GUID-объекта) и возвращает интерфейс IUnknown для взаимодействия с тем, кого породили.
|
|||
63
Рэйв
08.12.12
✎
18:23
|
При
IClassFactory->CreateInstance IClassFactory - объект или ссылка? |
|||
64
Рэйв
08.12.12
✎
18:23
|
Жду ответа на (63)
|
|||
65
Рэйв
08.12.12
✎
18:25
|
ладно..чтобы понятнее
Объект или указаьтель? |
|||
66
Torquader
08.12.12
✎
18:26
|
Начнём с того, что IClassFactory - это интерфейс, то есть заведомо известный класс.
И правильнее писать вызов ClassFactory->lpVtbl->CreateInstance, так как для вызова используется виртуальная таблица функций класса - которая заведомо известна двум процессам. Если писать на Си, на чём обычно пишу я, то объект - это указатель на память, где что-то живёт. Ссылка - это указатель на таблицу (HANDLE), где указано на то место в памяти, где кто-то живёт. |
|||
67
Torquader
08.12.12
✎
18:28
|
Реально из Dll для реализации IClassFactory передаётся только таблица указателей на функции, реализующие этот интерфейс - и больше ничего - никаких объектов и ссылок - то есть массив int4 (или int8 для 64) и всё.
|
|||
68
Рэйв
08.12.12
✎
18:29
|
(66)Будь проще, чувак!:-)
1. IClassFactory.CreateInstance тогда IClassFactory- объект 2. IClassFactory->CreateInstance тогда IClassFactory- указатель |
|||
69
Рэйв
08.12.12
✎
18:30
|
все просто. Укузатель не может взять через оператор "." ..у него не отчего брать
|
|||
70
Рэйв
08.12.12
✎
18:30
|
(69)Указатель - тлько адрес содержит
|
|||
71
Torquader
08.12.12
✎
18:35
|
Точка используется для доступа к полям класса или структуры.
Стрелочка используется для доступа к полям класса и структуры по указателю. |
|||
72
Рэйв
08.12.12
✎
18:36
|
(71)Молодец))
А теперь ответь -ыв указателях у нас что? |
|||
73
Torquader
08.12.12
✎
18:36
|
Например, в php наоборот - доступ к полям объектов через стрелочку, а точка - она используется для соединения строк.
Это всё от языка программирования зависит. А объект - это некоторый участок памяти. |
|||
74
Рэйв
08.12.12
✎
18:39
|
(73)Ты так и не ответил на вопрос:-)
Ладно я отвечу. В указателях у нас адреса памяти где лежат плюшки и пряники:-) |
|||
75
Torquader
08.12.12
✎
18:47
|
(74) На самом деле, указатель у нас указывает только на таблицу функций, которую мы передали системе для взаимодействия с нашими объектами.
И в таблице лежат только указатели на функции, которые менеджер взаимодействия будет вызывать, когда их запросят с другой стороны. Реально же сам объект, который предоставляет подобный интерфейс, живёт где-то в памяти приложения - там где мы его разместим. Он просто должен помнить, что у него запросили такой-то интерфейс, и что он должен ожидать вызова функций этого интерфейса. |
|||
76
Torquader
08.12.12
✎
18:48
|
Собственно говоря, интерфейс - это специальный объект, который создаётся для взаимодействия между двумя основными объектами.
|
|||
77
Torquader
08.12.12
✎
18:54
|
Ладно - мне пора есть - пора заканчивать "беседу троллей", так как она явно неконструктивна.
|
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |