Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Вниз

AccessViolation при закрытии клиента   Найти похожие ветки 

 
Manfred   (2004-07-26 18:00) [0]

Ситуация: midas на сокетах, база Access, технология ADO. В клиенте MDI Form. В ней одновременно открыты две формы MDI Child. Одна из форм содержит связь master-detail, два TClientDataset, два TDatasource, два TDBGridEh, другая форма один TClientDataset, TDataSource, TDBGridEh. Формы обращаются к разным таблицам базы. При закрытии клиента destroy для формы с одним гридом проходит нормально. Срабатывает OnActivate для другой формы, в котором происходит закрытие, смена текста SQL запроса, а потом открытие двух TClientDataset`ов. При открытии TClientDataset происходит AccessViolation. Почему...
Ошибка возникает при TClientDataset.open. Такой же баг на другой форме вылечился заменой Close,Open на Refreshe.


 
Johnmen ©   (2004-07-26 18:09) [1]

Потому, что практика работы с НД в OnActivate глубоко порочна.


 
Manfred   (2004-07-26 18:14) [2]

Ваш выбор  OnShow? :)
Я согласен,но всетаки почему проходит refresh и не проходит Close
Open Странно


 
Johnmen ©   (2004-07-26 18:27) [3]

1. Как выглядит код обработчика ?
2. Полный текст AV ?


 
Manfred   (2004-07-26 18:36) [4]

procedure TMonitoringFrm.FormActivate(Sender: TObject);
begin
 HeadClientDataSet.close;
 MakeSQLForMarshrut;
 HeadClientDataSet.Open;
Access violation at address 004FA560 in module "ClientApp.exe". Read of address 00000008.
 ReisClientDataSet.close;
 MakeSQLForReis;
 ReisClientDataSet.Open;
end;


 
Плохиш ©   (2004-07-26 18:49) [5]


> Manfred   (26.07.04 18:36) [4]

Понятие такое есть "отладка". Вот и занимайся. А ошибка как всегда в 17й строке.


 
Johnmen ©   (2004-07-27 09:22) [6]

> Manfred   (26.07.04 18:36) [4]

1. Что скрывается за MakeSQLForMarshrut ?
2. Как здесь удается обойти AV с пом. Refresh ?


 
Manfred   (2004-07-27 10:26) [7]

To Плохих> Представляете я в курсе.

To Johmen> Дело не в MakeSqlForMarshrut.
Есть аналогичная ошибка с ClienDataSet который связан с таблицей а не запросом. Если у него стоит Close/open выдается таже ошибка
если сделать вот так:
if  CityClientDataSet.state= dsInactive then
  CityClientDataSet.Open
else CityClientDataSet.Refresh;
То проходит на ура.
Если трайсить после Open идет по DBGridEh модулям и в конце концов пишет вот такое:
---------------------------
Debugger Fault Notification
---------------------------
Project C:\Documents and Settings\Peter\??????? ????\Midas ?? Progr1\client\ClientApp.exe raised too many consecutive exceptions: "access violation at 0x00000000: read of address 0x00000000". Process Stopped. Use Step or Run to continue.
---------------------------
OK   Help  
---------------------------


 
Johnmen ©   (2004-07-27 10:41) [8]

Какие события прописаны для MonitoringFrm и HeadClientDataSet ?
Да, и ещё. Что означает "При закрытии клиента " ?


 
Manfred   (2004-07-27 10:54) [9]

Закрытие - Если нажимают крестик у главного MDI окна программы клиента,когда открыты два дочерних окна и причем фокус ввода на другом окне ,не на том в OnActivate которого происходит ошибка.

У  HeadClientDataSet нет обработчиков

Обработчики у формы:

//размеры формы из Инишника
procedure TMonitoringFrm.FormCreate(Sender: TObject);
begin
 ReadFormSizeFromIni(nil,self);
end;
procedure TMonitoringFrm.FormActivate(Sender: TObject);
begin
if  ListOfYearsClientDataSet.state= dsInactive then
  ListOfYearsClientDataSet.Open
else ListOfYearsClientDataSet.Refresh;

if  CityClientDataSet.state= dsInactive then
  CityClientDataSet.Open
else CityClientDataSet.Refresh;

 HeadClientDataSet.close;
 MakeSQLForMarshrut;
 HeadClientDataSet.Open;

 ReisClientDataSet.close;
 MakeSQLForReis;
 ReisClientDataSet.Open;
end;

procedure TMonitoringFrm.FormClose(Sender: TObject;
 var Action: TCloseAction);
begin
 Action:=cafree;
 MonitoringFrm:=nil;
end;

//размеры формы в Инишник
procedure TMonitoringFrm.FormDestroy(Sender: TObject);
begin
 WriteFormSizeToIni(nil, self.Name,FormRecordInit(self));
end;


 
Johnmen ©   (2004-07-27 11:01) [10]

Похоже всё дело в последовательности обрабатываемых сообщений для MDI-ной формы. Посмотри, какая она. Насколько помню, сначала придет дестрой, а потом придет активейт...
Короче, см.пост [1]. + к нему OnDeactivate.


 
Manfred   (2004-07-27 11:15) [11]

Desroy для верхней,которая в фокусе,Activate для имевшей фокус перед этим,дестрой для нее,затем активате для предыдущей,дестрой для нее и наконец дестрой для главной(почему-то без активате)


 
Skyle ©   (2004-07-27 11:37) [12]

Слежу за вашим обсуждением ибо недавно поимел подобный AV.
Только ситуация несколько иная..

Псевдокод
procedure TForm1.DoIt;
begin
 with TForm2.Create(Self) do
 try
   ShowModal;
   RefreshData; //Это метод TForm1
 finally
   Free;
 end;
end;


Далее
procedure TForm1.RefreshData;
begin
 if cds.Active then
   cds.close;
 cds.Params.ParamByName(......
 .......
 cds.Open;
end;


На TForm2 лежит несколько гридов, из них 2 доступны для редактирования. Напр. Editable1, Editable2. Остальные - R/O.
Отладчик дельфей:
В TForm2.OnDestroy;
try
 Editable1.Free;
except
 ShowMessage("Editable1");
 Raise;
end;
try
 Editable2.Free;
except
 ShowMessage("Editable2");
 Raise;
end;

Сообщения выводятся только эти и бессистемно. Назависимо от видимости гридов или редактирования какого-либо. Была идея, что проблема в InplaceEditor, но как-то убедиться в этом не удалось...

MemProof выдаёт сообщение, что "удаление несуществующего" происходит примерно при таком CallStack
DoIt
RefreshData
cds.Open
..где-то унутре TClientDataSet, в различных местах.

Но при этом, если переписать TForm1.DoIt как

with TForm2.Create(Self) do
try
 ShowModal;
 RefreshData;
finally
 try
   Free;
 except
   ShowMessage("Here");
   Raise;
 end;
end;

сообщение "Here" мы получаем, а вот в случае
finally
 if ExceptObject <> nil then
   ShowMessage("Before");
 Free;
end;


не даёт сообщения "Before".
Т.о. вроде как AV и не наведённый...
Ничего не понимаю, но очень хочется разобраться...


 
Manfred   (2004-07-27 11:56) [13]

To Skyle >А зачем вы гридам free делаете,почему не доверяете это дело форме владельцу?


 
Skyle ©   (2004-07-27 12:25) [14]


> Manfred   (27.07.04 11:56) [13]

Потому что удалось отладчиком получить AV в деструкторе WinControl, где удаляются все лежащие на нём контролы. Этот цикл был перенесён в деструктор формы, где уже без труда было вычленено 2 виновника. Также это помогло убедиться в том, что порядок уничтожения контролов не влияет на появление AV.

Я до этого не пользовался MemProof, и, по сути, связываю наши ситуации только на основании его показаний на место ошибки.
Всё остальное против того, что ошибка в cds.Open.
Особенно, если учесть, что
The error text is not generated by MemProof, but is retrieved from Windows by calling GetLastError. Unfortunatelly, some WinAPI functions do not set the LastError variable, even though the Win32 documentation says that they should.

Но вот только предыдущие сообщения об ошибке не внесли ясности...

Из-за того, что для получения AV в моём случае надо очень быстро махать мышкой и не всегда, тормознув в отладчике, его получаешь, была идея, что это работа какого-либо таймера. Да, на TForm2 есть таймер, но после выхода из ShowModal он не должен работать.
Реализация ShowModal при беглом её просмотре подсказывает мне, что WM_Timer там пролезть не должен. Как и всякие WM_Paint и иже с ними имеющиеся обработчики. То есть, есть мнение, что после выхода из ShowModal обработчики сообщений (WM_Timer, WM_PAINT конкретно) выполняться не должны. Я даже отключал всё, что можно - эффект тот же самый.

В общем, мне не удалось решить эту проблему и я просто надеюсь почерпнуть каких-либо идей из текущего обсуждения.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.08.22;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.49 MB
Время: 0.036 c
14-1091519097
DSKalugin
2004-08-03 11:44
2004.08.22
почему следующая фраза вешает ворд ХП???


4-1088894848
Spy.RU
2004-07-04 02:47
2004.08.22
Доступ к строке инициализации модема


14-1091616142
Bless
2004-08-04 14:42
2004.08.22
Зачем нужен фаервол?


1-1091703629
Spike
2004-08-05 15:00
2004.08.22
Открыть папку и выделить в ней нужный мне файл...


14-1091624567
by
2004-08-04 17:02
2004.08.22
Методики разработки ПО





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский