Имя: Пароль:
1C
 
ВК 1С на .NET: призрак OLE-доступа или почему 1С зависает в памяти
0 romix
 
модератор
19.12.05
10:00
Зацените мою новую статью в Книге знаний:
Внешние компоненты 1С на .NET: призрак OLE-доступа или почему 1С зависает в памяти
(на форуме был такой вопрос, решил разобраться).
Оказывается, что 1С в этом режиме работы все время виснет, как лошадь, которая выкурила каплю никотина (если корректно не завершать работу с объектами). Поправки и дополнения приветствуются.

P.S. Движок kb.mista.ru поддерживает добавление своих статей и правку чужих в режиме энциклопедии (наподобии wikipedia).
1 romix
 
модератор
19.12.05
14:40
Апнуть что ли.. Тут точно есть 2 или 3 человека, которым это интересно. :-)
2 MMF
 
19.12.05
14:47
"Это и понятно: 1С должна «как следует» загрузиться, после чего сможет предоставлять различные внешние  интерфейсы." - кто в кого загружается, компонента в 1С или 1С в компоненту?
3 romix
 
модератор
19.12.05
14:55
(2) Короче, компонента принадлежит адресному пространству процесса 1С, и в момент init она еще не видит AppDispatch. А так в общем все верно или есть приколы, как думаешь?
4 MMF
 
19.12.05
15:07
(3) в целом - так себе, запрашивать AppDispatch нужно непосредственно перед использованием и освобождать как только стал ненужным. И не нужен никакой net.Закрыть().
5 romix
 
модератор
19.12.05
15:14
(4) А ничего что я сразу освобождаю при получении объекта:

obj1C = V7Data.V7Object.AppDispatch
Marshal.Release(Marshal.GetIDispatchForObject(obj1C))

net.Закрыть() действительно тут не нужен - он по другому случаю.
А именно, по случаю невозможности корректно освободить глобальную переменную ссылочного типа во время ее юзания, когда она юзается в параметрах процедуры или функции.
6 MMF
 
19.12.05
15:22
(5) ты уменьшил счетчик ссылок на idispatch интерфейса 1С. Разве это == освобождаю? ИМХО, нехорошо хранить интерфейс 1С-ки.
7 romix
 
модератор
19.12.05
15:48
(6) Ну да, уменьшил (причем, сразу же). Это корректно, как думаешь? Или надо как-то иначе уменьшать счетчик?

А не знаешь такую тему, если известен id процесса, и я хочу (например, при закрытии процесса) вычистить все счетчики idispatch в 0. Такое возможно, как думаешь? А то имхо потенциальная кора, когда все виснет в памяти.
8 MMF
 
19.12.05
16:00
(7) я про васик ничего не знаю. По второму пункту - невозможно.
9 romix
 
19.12.05
17:10
(8) В .NET что бейсик, что C# - отличия только внешние (комментарии, например, там начинаются //, а в бейсике - символом '). А вот от Дельфи есть различие в закрытии того же AppDispatch.

То есть нельзя перебрать все OLE-ссылки процесса и грохнуть их? Блин подстава.
А при получении ссылки же ее можно сразу же закрывать? Например, я получаю параметр (типа документ или справочник), и хочу сразу же его закрывать, чтобы не было никаких ссылок. Как думаешь это реально? Или надо ссылку открытой все время держать?
10 YuriPar
 
30.12.05
11:30
romix прав
Только в конце дай Marshal.ReleaseComObject (AppDispatch)
все освободиться,Сборщик мусора сам уберет
так как вы его уже раз уменьшили (Release) никаких ссылок
уже не будет
Есть еще суровый малодокуметированный Wrapper
Если передан объект агрегатного типа в пределах процедуры(а объект в модуле 1С
не объявлен на уровне модуля) то "грохать" его не надо CCW сама грохнет
А вообще лучше считать объекты в ВК тогда и выгрузишь корректно
типа
private static int count=0;
void Init()
{
  count+=1;
}
void Done()
{
count-=1;
if(count==0)
{
бъем все компонента выгружается
}
}
Ошибка? Это не ошибка, это системная функция.