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 имеет неочевидную особенность: после выполнения переменная цикла сохраняет значение, присвоенное ей на последней итерации цикла. Эта особенность может приводить к появлению ошибок 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
По поводу "если явно не выполняется очистка переменной цикла после завершения цикла":
Судя по тексту примера переменная цикла это DataSetLine, а очищается только Reference - поэтому непонятно, это правильный пример или нет.
Не соглашусь с пунктом "Особенности работы цикла foreach" У меня была такая история:
и все это провоцировало как раз ESBWrapperAlive со всеми вытекающими
Пришлось поменять на While, все стало работать как надо
С тех пор, только while
while в работе с коллекциями выглядит однозначно хуже. Кроме того, он провоцирует ошибку с забытым .Next
А почему в примере
Нельзя было поменять местами последние две строки, вместо того, чтобы переделывать на while?
Потому что как раз, если поменять местами, то это явный случай неправильной работы со ссылками - детальный набор данных уже отпустили, а его запись держим.
А что означает "запись держим"? Вы же сначала обнулите ссылку на детальный набор данных, а потом на запись. Ничего держаться не будет.
на строчке ds3=nil, в таком случае, вы и получите предупреждение ESBWrapperAlive, потому что в памяти еще осталась ссылка на запись, а на сам набор данных уже ссылки нет.
Т.е. если написать вот так:
то все равно будет ошибка ESBWrapperAlive?
Есть вопрос насчет исключения ESBWrapperAlive. Подключаю к типу карточки WebControl, там на javascript открывается набор данных dataset(1) и набор данных избранных. Все переменные обновляются, но ошибка все равно возникает о том, что набор данных не уничтожен, что и вызывает Access Violation. Знаете ли, в чем эта причина и как это исправить?
Лев, а в логах билдера что?
Петр, получаю следующее сообщение в логе:
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
Можете еще описать что делает пользователь? Похоже нажимает какую то кнопку и потом идет работа с некой формой, а после этого все падает.
Ну и да, надо полный код посмотреть
Петр, пользователь просто открывает карточку поручения. При показе карточки срабатывает открытие 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(); - можно было бы в одну точку разделить её и тоже обнулять, хотя в ошибке конечно явно указано на детальный раздел.
можно еще попробовать вообще убрать обнуления, как ни странно, иногда это тоже помогает
Если воспроизводится стабильно, можете пакет разработки выложить, попробуем погонять у нас.
Авторизуйтесь, чтобы написать комментарий