Исключение ESBWrapperAlive и случаи его появления

Опубликовано:
10 декабря 2014 в 14:12
  • 13

ESBWrapperAlive - это диагностическое исключение для определения мест неправильной работы со ссылками на объекты системы. Оно может сопровождаться генерацией наведенных исключений, например Access Violation.

В статье рассмотрим неcколько ситуаций, при которых возможно возникновение данного исключения.

Неправильный порядок очистки ссылок на связанные объекты

Например такой код на ISBL приведет к появлению "ESBWrapperAlive Враппер набора данных не уничтожен. Компонента: Пользователи, индекс набора данных: 1":

App = Application.CloneApplication
Reference = App.ReferencesFactory.ПОЛ.GetComponent
DetailDataSet = Reference.DetailDataSet(1)
Reference = App.ReferencesFactory.ГПЛ.GetComponent

Причина возникновения ошибки в том, что удерживается ссылка на детальный набор данных справочника ПОЛ (справочник "Пользователи") при том, что уже отпущена ссылка на сам справочник.

Способы исправления:

  • Использовать для справочника ГПЛ (справочник "Группы пользователей") другую переменную:
App = Application.CloneApplication
Reference = App.ReferencesFactory.ПОЛ.GetComponent
DetailDataSet = Reference.DetailDataSet(1)
Reference1 = App.ReferencesFactory.ГПЛ.GetComponent
  • сначала завершить все работы со справочником ПОЛ и очистить ссылки в порядке обратном их означиванию:
App = Application.CloneApplication
Reference = App.ReferencesFactory.ПОЛ.GetComponent
DetailDataSet = Reference.DetailDataSet(1)
...
DetailDataSet = nil
Reference = App.ReferencesFactory.ГПЛ.GetComponent

Особенности работы цикла foreach

Цикл foreach имеет неочевидную особенность: после выполнения переменная цикла сохраняет значение, присвоенное ей на последней итерации цикла. Эта особенность может приводить к появлению ошибок ESBWrapperAlive, если явно не выполняется очистка переменной цикла после завершения цикла.

Пример

Reference = References.ПОЛ.GetComponent
Reference.Open
Reference.OpenRecord
DetailDataSet = Reference.DetailDataSet(1)
foreach DataSetLine in DetailDataSet
  ...
endforeach
Reference = nil

Неочевидная логика работы с объектами

Сюда относятся ситуации, которые на первый взгляд могут показаться дефектами, но на самом деле так сделано специально.

Рассмотрим пример:

Query = CreateQuery()
Query.CommandText = 'select * from XIni'
Query.Open
Field1 = Query.Fields('ValuePar')
...
Query.Close
Query.Open

Этот код приведет к генерации исключения "ESBWrapperAlive Внутренний объект поля TSBStringField не уничтожен". Дело в том, что поля запроса пересоздаются при его открытии. Чтобы избежать ошибок необходимо очищать ссылки на поля до повторного закрытия запроса:

Query = CreateQuery()
Query.CommandText = 'select * from XIni'
Query.Open
Field1 = Query.Fields('ValuePar')
...
Query.Close
Field1 = nil
Query.Open
25
Подписаться

Комментарии

Потому что как раз, если поменять местами, то это явный случай неправильной работы со ссылками - детальный набор данных уже отпустили,  а его запись держим.

Потому что как раз, если поменять местами, то это явный случай неправильной работы со ссылками - детальный набор данных уже отпустили,  а его запись держим.

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

на строчке ds3=nil, в таком случае, вы и получите предупреждение ESBWrapperAlive, потому что в памяти еще осталась ссылка на запись, а на сам набор данных уже ссылки нет.
 

Т.е. если написать вот так:

ds3=doc.Detaildataset(3)
forEach rec in ds3
	rec.Requisites…..
endForeach
ds3=nil
rec=nil

то все равно будет ошибка ESBWrapperAlive?

Есть вопрос насчет исключения ESBWrapperAlive. Подключаю к типу карточки WebControl, там на javascript открывается набор данных dataset(1) и набор данных избранных. Все переменные обновляются, но ошибка все равно возникает о том, что набор данных не уничтожен, что и вызывает Access Violation. Знаете ли, в чем эта причина и как это исправить?

Лев Кудряшов: обновлено 01.03.2017 в 09:08

Лев, а в логах билдера что? 

Петр, получаю следующее сообщение в логе:

01.03.2017    13:48:42.004    Main(4180)    DIRECTUM    dbo    Debug    ESBWrapperAlive    Враппер набора данных не уничтожен. Компонента: Избранные исполнители, индекс набора данных: 1. <- SBQuery.TSBCustomDataSet.Destroy (2698) <- SBDS.TSBDataSet.Destroy (2577) <- System.TObject.Free (15655) <- System.Classes.TComponent.Destroy (15698) <- Db.TDataSet <- SBDS.TSBDataSet.Destroy (2577) <- System.TObject.Free (15655) <- SBQuery.TSBCustomDataSetWrapper.Destroy (7021) <- SBDS.TSBDataSetWrapper.Destroy (8859) <- System.TInterfacedObject._Release (36476) <- System.@IntfClear (35702) <- SBRef.TSBReferenceWrapper.Destroy (325) <- System.TObject.Free (15655) <- Olectrls.TOleControl.DefaultHandler <- Controls.TWinControl.WMDestroy <- Controls.TWinControl.WndProc <- Olectrls.TOleControl.WndProc <- Controls.TWinControl.MainWndProc <- System.Classes.StdWndProc (17059) <- Forms.TCustomForm.DestroyWindowHandle <- Forms.TCustomForm <- SBVistaFm.TSBVistaForm.Destroy (229) <- SBLocalizeControls.TSBLocalizeForm.Destroy (1464) <- SBScaledFm.TSBScaledForm.Destroy (124) <- dxRibbonForm.TdxCustomRibbonForm.Destroy (452) <- SBShortCutHandler.TSBShortCutHandledForm.Destroy (1289) <- SBFunctionHelpFm.TSBFunctionHelpForm.Destroy (415) <- System.TObject.Free (15655) <- Controls.TControl.WndProc <- Controls.TWinControl.WndProc <- Forms.TCustomForm.WndProc <- SBVistaFm.TSBVistaForm.WndProc (364) <- dxRibbonForm.TdxCustomRibbonForm.WndProc (2106) <- cxControls.TcxWindowProcLinkedObject.DefaultProc (8404) <- dxShadowWindow.TdxShadowWindow.OwnerWindowWndProc (334) <- cxControls.TcxWindowProcLinkedObjectList.WndProc (8516) <- Controls.TWinControl.MainWndProc <- System.Classes.StdWndProc (17059) <- Forms.TApplication.ProcessMessage <- Forms.TApplication.HandleMessage <- SBShortCutHandler.TSBShortCutHandledForm.ShowModal (1876) <- SBFm.TSBCustomForm.ShowModal (1169) <- SBFm.TSBCustomForm.PrepareAndShow (1554) <- SBFm.TSBCustomForm.InternalShow (1419) <- SBFm.TSBCustomForm.Show (1578) <- SBFm.TSBCustomFormWrapper.Show (849) <- SBISBLDevFunc.EditDataSetEventTexts (1611) <- SBInter.TSBInter.CalculateFunction (5810) <- SBInter.TSBInter.ExecuteFunction (2927) <- SBInter.TSBInter.ExecuteTermExprn (2409) <- SBInter.TSBInter.ExecuteScript (2983) <- SBInter.TSBInter.ExecutePrepared (5468) <- SBInter.TSBInter.Execute (5428) <- SBInter.TSBInter.Execute (5360) <- SBDataSetComp.TSBDataSetComponentWrapper.ExecuteISBLActionHandler (745) <- SBView.TSBCustomViewWrapper.ButtonsActionISBLHandler (5001) <- SBView.TSBCustomViewWrapper.ExecuteHandler (2787) <- System.Classes.TBasicAction.Execute (16558) <- Actnlist.TCustomAction.Execute <- SLStandardAction.TSLStandardAction.Execute (1071) <- System.Classes.TBasicActionLink.Execute (16469) <- dxBar.TdxBarItem.DoClick (20726) <- dxBar.TdxBarItem.DirectClick (20712) <- dxBar.TdxBarItemControl.ControlUnclick (39042) <- dxBar.TdxBarButtonControl.ControlUnclick (41167) <- dxBar.TCustomdxBarControl.DoLButtonUp (22022) <- dxBar.TdxBarControl.DoLButtonUp (51909) <- dxBar.TCustomdxBarControl.WMLButtonUp (21329) <- dxBar.TdxBarDockedControl.WMLButtonUp (48569) <- Controls.TControl.WndProc <- Controls.TWinControl.WndProc <- dxBar.TCustomdxBarControl.WndProc (21681) <- dxBar.TdxBarControl.WndProc (52786) <- Controls.TWinControl.MainWndProc <- System.Classes.StdWndProc (17059) <- Forms.TApplication.ProcessMessage <- Forms.TApplication.HandleMessage <- SBRte.Finalization (66) <- SBQuery.TSBCustomDataSet.Destroy (2698) <- SBDS.TSBDataSet.Destroy (2577) <- System.TObject.Free (15655) <- System.Classes.TComponent.Destroy (15698) <- Db.TDataSet <- SBDS.TSBDataSet.Destroy (2577) <- System.TObject.Free (15655) <- SBQuery.TSBCustomDataSetWrapper.Destroy (7021) <- SBDS.TSBDataSetWrapper.Destroy (8859) <- System.TInterfacedObject._Release (36476) <- System.@IntfClear (35702) <- SBRef.TSBReferenceWrapper.Destroy (325) <- System.TObject.Free (15655) <- Olectrls.TOleControl.DefaultHandler <- Controls.TWinControl.WMDestroy <- Controls.TWinControl.WndProc <- Olectrls.TOleControl.WndProc <- Controls.TWinControl.MainWndProc <- System.Classes.StdWndProc (17059) <- Forms.TCustomForm.DestroyWindowHandle <- Forms.TCustomForm <- SBVistaFm.TSBVistaForm.Destroy (229) <- SBLocalizeControls.TSBLocalizeForm.Destroy (1464) <- SBScaledFm.TSBScaledForm.Destroy (124) <- dxRibbonForm.TdxCustomRibbonForm.Destroy (452) <- SBShortCutHandler.TSBShortCutHandledForm.Destroy (1289) <- SBFunctionHelpFm.TSBFunctionHelpForm.Destroy (415) <- System.TObject.Free (15655) <- Controls.TControl.WndProc <- Controls.TWinControl.WndProc <- Forms.TCustomForm.WndProc <- SBVistaFm.TSBVistaForm.WndProc (364) <- dxRibbonForm.TdxCustomRibbonForm.WndProc (2106) <- cxControls.TcxWindowProcLinkedObject.DefaultProc (8404) <- dxShadowWindow.TdxShadowWindow.OwnerWindowWndProc (334) <- cxControls.TcxWindowProcLinkedObjectList.WndProc (8516) <- Controls.TWinControl.MainWndProc <- System.Classes.StdWndProc (17059) <- Forms.TApplication.ProcessMessage <- Forms.TApplication.HandleMessage <- SBShortCutHandler.TSBShortCutHandledForm.ShowModal (1876) <- SBFm.TSBCustomForm.ShowModal (1169) <- SBFm.TSBCustomForm.PrepareAndShow (1554) <- SBFm.TSBCustomForm.InternalShow (1419) <- SBFm.TSBCustomForm.Show (1578) <- SBFm.TSBCustomFormWrapper.Show (849) <- SBISBLDevFunc.EditDataSetEventTexts (1611) <- SBInter.TSBInter.CalculateFunction (5810) <- SBInter.TSBInter.ExecuteFunction (2927) <- SBInter.TSBInter.ExecuteTermExprn (2409) <- SBInter.TSBInter.ExecuteScript (2983) <- SBInter.TSBInter.ExecutePrepared (5468) <- SBInter.TSBInter.Execute (5428) <- SBInter.TSBInter.Execute (5360) <- SBDataSetComp.TSBDataSetComponentWrapper.ExecuteISBLActionHandler (745) <- SBView.TSBCustomViewWrapper.ButtonsActionISBLHandler (5001) <- SBView.TSBCustomViewWrapper.ExecuteHandler (2787) <- System.Classes.TBasicAction.Execute (16558) <- Actnlist.TCustomAction.Execute <- SLStandardAction.TSLStandardAction.Execute (1071) <- System.Classes.TBasicActionLink.Execute (16469) <- dxBar.TdxBarItem.DoClick (20726) <- dxBar.TdxBarItem.DirectClick (20712) <- dxBar.TdxBarItemControl.ControlUnclick (39042) <- dxBar.TdxBarButtonControl.ControlUnclick (41167) <- dxBar.TCustomdxBarControl.DoLButtonUp (22022) <- dxBar.TdxBarControl.DoLButtonUp (51909) <- dxBar.TCustomdxBarControl.WMLButtonUp (21329) <- dxBar.TdxBarDockedControl.WMLButtonUp (48569) <- Controls.TControl.WndProc <- Controls.TWinControl.WndProc <- dxBar.TCustomdxBarControl.WndProc (21681) <- dxBar.TdxBarControl.WndProc (52786) <- Controls.TWinControl.MainWndProc <- System.Classes.StdWndProc (17059) <- Forms.TApplication.ProcessMessage <- Forms.TApplication.HandleMessage <- SBRte.Finalization (66)    SBRte.exe    7.15.0.3114    10236    RRCAssignments#ctReference    INTANT\lkudryashov    False
 

Лев Кудряшов: обновлено 01.03.2017 в 10:15
Лев Кудряшов: обновлено 01.03.2017 в 10:48

Можете еще описать что делает пользователь? Похоже нажимает какую то кнопку и потом идет работа с некой формой, а после этого все падает. 

Ну и да, надо полный код посмотреть 

Петр, пользователь просто открывает карточку поручения. При показе карточки срабатывает открытие html файла, в котором срабатывает javascript код. Он отображает список Избранных. В последствии чего срабатывает описанное выше исключение. Предоставляю код метода, который подгружает избранных: 

function loadPerformers() {
                var name = "GTTFavoritePerformers";
                var currentRef = window.external.Form.View.Component;
                currentRef.OpenRecord();
                var currentAuthor = currentRef.Requisites("Employee").Value
                
                var performersRef = currentRef.Application.ReferencesFactory.ReferenceFactory(name).GetComponent();
                performersRef.Open();
                var currentAuthorRef = performersRef.Locate("Employee", currentAuthor);
                var disableCheckbox = currentRef.Form.Controls.FindControl("STDBEllipsis3").ReadOnly;
                
                if(currentAuthorRef) {
                    performersRef.OpenRecord();
                    var container = document.getElementById('body');
                    var toggleAllCheckbox = document.createElement('input');
                    toggleAllCheckbox.type = "checkbox";
                    toggleAllCheckbox.name = "toggleAll";
                    toggleAllCheckbox.style.marginTop = "0px";
                    toggleAllCheckbox.style.paddingTop = "0px";
                    if(disableCheckbox) {
                        toggleAllCheckbox.disabled = true;
                    }
                    toggleAllCheckbox.id = "toggleAll";
                    toggleAllCheckbox.onclick = (function() {
                        return function () {
                            toggle(this);
                        };
                    })();

                    var label = document.createElement('label');
                    label.htmlFor = "toggleAll";
                    label.appendChild(document.createTextNode("Выбрать всех"));

                    container.appendChild(toggleAllCheckbox);
                    container.appendChild(label);
                    
                    var performersDDS = performersRef.DetailDataSet(1);
                    var count = 1;
                    while(!performersDDS.EOF) {
                        var container = document.getElementById('body');
                        var checkbox = document.createElement('input');
                        //var perfomerT = performersDDS.Requisites("PerformerT").Value;
                        checkbox.type = "checkbox";
                        checkbox.name = "user111";
                        if(disableCheckbox) {
                            checkbox.disabled = true;
                        }
                        checkbox.value = performersDDS.Requisites("PerformerT").Value;
                        checkbox.id = "user_" + count;
                        checkbox.onclick = (function() {
                            return function () {
                                setPerformer(this.id, this.value);
                            };
                        })();

                        var label = document.createElement('label');
                        label.htmlFor = "user_" + count;
                        label.appendChild(document.createTextNode(performersDDS.Requisites("AdditionT").DisplayText));
                        
                        var paragraph = document.createElement('br');

                        container.appendChild(paragraph);
                        container.appendChild(checkbox);
                        container.appendChild(label);
                        // increase counter
                        count++;
                        // fill global employees array
                        employees.push(performersDDS.Requisites("PerformerT").Value);
                        //alert(performersDDS.Requisites("PerformerT").Value);
                        //perfomerT = null;
                        performersDDS.Next();
                    }
                    performersDDS = null;    
             
                                    }
                performersRef.Close();
                performersRef = null;
                currentRef = null;
              
            }

хм, вроде бы нет никакого явного криминала, попробуйте эту штуку удалить performersRef.Close(); 

или еще мне вот эта строка не нравится var performersRef = currentRef.Application.ReferencesFactory.ReferenceFactory(name).GetComponent(); - можно было бы в одну точку разделить её и тоже обнулять, хотя в ошибке конечно явно указано на детальный раздел. 

можно еще попробовать вообще убрать обнуления, как ни странно, иногда это тоже помогает

Если воспроизводится стабильно, можете пакет разработки выложить, попробуем погонять у нас. 

 

Авторизуйтесь, чтобы написать комментарий