Имя: Пароль:
1C
1С v8
Внешняя компонента 8.2 - Вк, не отрабатывает Done
,
0 lvi15
 
21.07.11
18:43
Добрый день, цепляю ВК, грузится что-то делает, но затем не выгружается, то есть в метод Done вообще не заходит и соответственно 1с остается в памяти( в версии 1с 8.0,1 все заходило и выгружало) Код примерно следующий:
....Описание интерфейса:
Imports System.Runtime.InteropServices
<Guid("AB634001-F13D-11d0-A459-004095E1DAEA"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)> _
Public Interface IInitDone
 Sub Init(<MarshalAs(UnmanagedType.IDispatch)> ByVal pConnection As Object)
 Sub Done()
 Sub GetInfo(ByRef pInfo() As Object)
End Interface
.....
и далее в коде ВК:
Public Class VnKomp1c
   Implements IInitDone
   Implements ILanguageExtender
   Const c_AddinName As String = "Conn1c"
#Region "Переменные"
   'Dim obj1C As Object 'Объект 1С
   Dim g_flagInit As Boolean 'Признак, что инициализация obj1C уже прошла
   <MarshalAs(UnmanagedType.IDispatch)> Dim obj1C As Object
#End Region
#Region "IInitDone implementation"
   ' Обязательно для COM инициализации
   Public Sub New()
   End Sub
   '--Инициализируем объект 1с в глобальную переменную
   Private Sub Init(<MarshalAs(UnmanagedType.IDispatch)> ByVal pConnection As Object) Implements IInitDone.Init
       MsgBox("init")  '--- ЭТО РАБОТАЕТ
       V8Data.V8Object = pConnection
       '--Инициализируем объект 1с в глобальную переменную
       If g_flagInit = False Then
           obj1C = V8Data.V8Object.AppDispatch
           Marshal.Release(Marshal.GetIDispatchForObject(obj1C))
           g_flagInit = True
       End If
   End Sub
   '--Усе освобождаем - не поучаецца все освободить - гдето идет запуск экземпляров 1с...
   Private Sub Done() Implements IInitDone.Done
       MsgBox("Done") '--- ЭТО ПРИ ЗАКРЫТИИ НЕ РАБОТАЕТ????
       obj1C = Nothing
       V8Data.V8Object = Nothing
       GC.Collect()
       GC.WaitForPendingFinalizers()
       'GetDatWsService = Nothing
   End Sub
       Private Sub GetInfo(ByRef pInfo() As Object) Implements IInitDone.GetInfo
       pInfo.SetValue("2000", 0)
   End Sub
..............
И на всякий случай описание V8Data

Friend Class V8Data
   Public Shared Property V8Object() As Object
       Get
           Return m_V8Object
       End Get
       Set(ByVal Value As Object)
           m_V8Object = Value
           ' Вызываем неявно QueryInterface
           m_ErrorInfo = CType(Value, IErrorLog)
           m_AsyncEvent = CType(Value, IAsyncEvent)
           m_StatusLine = CType(Value, IStatusLine)
       End Set
   End Property

   Public Shared ReadOnly Property ErrorLog() As IErrorLog
       Get
           Return m_ErrorInfo
       End Get
   End Property

   Public Shared ReadOnly Property AsyncEvent() As IAsyncEvent
       Get
           Return m_AsyncEvent
       End Get
   End Property

   Public Shared ReadOnly Property StatusLine() As IStatusLine
       Get
           Return m_StatusLine
       End Get
   End Property

   Private Shared m_V8Object As Object
   Private Shared m_ErrorInfo As IErrorLog
   Private Shared m_AsyncEvent As IAsyncEvent
   Private Shared m_StatusLine As IStatusLine

End Class

Может для 8.2 есть какие-то особенности???
С Уважением Л. Владимир
1 lvi15
 
22.07.11
11:34
Может кто сталкивался?
2 loh_pedalny
 
22.07.11
12:00
а в коде конфы переменная освобождается?
3 lvi15
 
22.07.11
12:31
Спасибо за ответ, у меня в обработке 1с сделано так:

Процедура ПриОткрытии()
  ПодключитьВнешнююКомпоненту("AddIn.VnKomp");
  workVnKomp  =  Новый ("AddIn.VnKomp");
...........

Переменная  workVnKomp   определена в реквизитах обработки, соответственно она доступна во всех модулях и формах обработки, поставил <ПриЗакрытии workVnKomp = null> Не помогает, то есть в событие <Done> в net-сборке вообще не заходит при закрытии обработки, ну еще вопрос так можно поставить -  а как закрыть ВК из обработки 1с, где оно вызывается?
4 lvi15
 
22.07.11
15:23
Сделал в ВК еще один метод methClear, в котором принудительно вызываю этот самый Done, а в обработке на события ПриЗакрытии и ПередЗакрытием посадил вызов  
workVnKomp.Clear() - вроде как в памяти все стало очищаться, но все равно непонятно - ведь этот самый Done во внешней компоненте должен автоматически запускаться при закрытии обработки??
5 ДенисЧ
 
22.07.11
15:24
(4) Нет. ВК выгружаются при завершении работы 1с.
6 lvi15
 
25.07.11
13:29
Я тоже так считал и считаю, но как "говорится":
 в Done - я поставил MsgBox("Done"), и после принудительного вызова он отбарабанивает два раза, - на вызов Done ну и после этого на собственно закрытие, а если принудительно не вызывать, то ни разу, ну и естественно оно остается в памяти
7 VlVlSt
 
30.07.11
17:04
Добрый день.
Пытался сделать remoting server в ВК на C#. Как только вызываю AppDispatch (в remoting объекте), то 1С не вызывает Done при закрытии в ВК. Всем объектам присваиваю null, вызываю GC.Collect(), GC.WaitForPendingFinalizers() и т.д. Принудительный вызов Done ничего не даёт. Даже уже и не знаю как освободить объекты.
Причём если закрыт 1С и потом вызвать remoting объект после этого, то в большинстве случаев 1С выгружает ВК (с вызовом Done) и процесс корректно завершается.
Основная теорема систематики: Новые системы плодят новые проблемы.