Поиск:

Ответ в темуСоздание новой темы Создание опроса
> ADO: Проблема с асинхронным выполнением запросов, Как правильно обработать ошибки? 
:(
    Опции темы
Петрович
  Дата 1.10.2007, 11:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Решил тут воспользоваться возможностью асинхронного исполнения запросов в ADO. Но, столкнулся с проблемой корректной обработки ошибок. 

Для демонстрации, сделал простейший пример.
1. Бросил на форму компонент Memo1 для протоколирования происходящих событий

2. Бросил на форму компонент ADOConnection1 назначил ему два обработчика событий:

OnBeforeConnect - для настройки соединения с демонстрационной БД поставляемой с Delphi:
Код

procedure TForm1.ADOConnection1BeforeConnect(Sender: TObject);
begin
  ADOConnection1.ConnectionString := 'FILE NAME=' + DataLinkDir + '\DBDEMOS.UDL';
  ADOConnection1.LoginPrompt := False;
end;


OnExecuteComplete - для протоколирования в Memo1 результата выполнения запросов
Код

procedure TForm1.ADOConnection1ExecuteComplete(Connection: TADOConnection;
  RecordsAffected: Integer; const Error: Error; var EventStatus: TEventStatus;
  const Command: _Command; const Recordset: _Recordset);
begin
  case EventStatus  of
    esOK            : Memo1.Lines.Add('ExecuteComplete esOK ('+IntToStr(RecordsAffected)+')');
    esErrorsOccured : Memo1.Lines.Add('ExecuteComplete esErrorsOccured: '+Error.Description);
    esCantDeny      : Memo1.Lines.Add('ExecuteComplete esCantDeny');
    esCancel        : Memo1.Lines.Add('ExecuteComplete esCancel');
    esUnwantedEvent : Memo1.Lines.Add('ExecuteComplete esUnwantedEvent');
    else              Memo1.Lines.Add('ExecuteComplete unknown '+IntToStr(Ord(EventStatus)));
  end;
  EventStatus := esUnwantedEvent;
end;


3. Бросил на форму компонент Button1 и назначил ему обработчик события OnClick для отключения ADOConnection1 от БД:
Код

procedure TForm1.Button1Click(Sender: TObject);
begin
  try
    if  ADOConnection1.Connected  then begin
      Memo1.Lines.Add('Before do Close');
      ADOConnection1.Close;
      Memo1.Lines.Add('After do Close');
    end;
  except on e :Exception do
    Memo1.Lines.Add('Exeption on Close: '+e.Message);
  end;
end;


4. Бросил на форму компонент Button2 и назначил ему обработчик события OnClick для запуска асинхронного исполнения запроса:
Код

procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Clear;
  try  ADOConnection1.Close;  except  end;
  try
    Memo1.Lines.Add('Before do valid Execute');
    ADOConnection1.Execute('DELETE FROM [Customer] WHERE CustNo<>CustNo',cmdText,[eoAsyncExecute]);
    Memo1.Lines.Add('After do valid Execute');
  except on e :Exception do
    Memo1.Lines.Add('Exeption on valid Execute: '+e.Message);
  end;
end;


Не пугайтесь, реально, этот запрос ничего не удалит т.к. условие CustNo<>CustNo в принципе не выполнимо smile

Теперь, запускаем проект и жмем Button2, дожидаемся появления в Memo1 строк:
Код

Before do valid Execute
After do valid Execute
ExecuteComplete esOK (0)

После этого жмем Button1, и в итоге в Memo1 имеем:
Код

Before do valid Execute
After do valid Execute
ExecuteComplete esOK (0)
Before do Close
After do Close

Т.е., все как и предполагалось. 
А теперь, усложним ситуацию. Для этого добавим еще одну кнопку Button3 со следующим кодом обработчиком OnClick:
Код

procedure TForm1.Button3Click(Sender: TObject);
begin
  Memo1.Clear;
  try  ADOConnection1.Close;  except  end;
  try
    Memo1.Lines.Add('Before do invalid Execute');
    ADOConnection1.Execute('DELETE FROM [НесуществующаяТаблица] WHERE CustNo<>CustNo',cmdText,[eoAsyncExecute]);
    Memo1.Lines.Add('After do invalid Execute');
  except on e :Exception do
    Memo1.Lines.Add('Exeption on invalid Execute: '+e.Message);
  end;
end;

Обратите внимание на то что в исполняемом запросе идет обращение к несуществующей в БД таблице. Т.е., этот запрос не может быть исполнен без ошибки.
А теперь, запустим проект и попытаемся выполнить этот ошибочный запрос нажатием Button3.
В Memo1 получим:
Код

Before do invalid Execute
After do invalid Execute
ExecuteComplete esErrorsOccured: Ядро базы данных Microsoft Jet не может найти входную таблицу или запрос 'НесуществующаяТаблица'.  Проверьте существование таблицы или запроса и правильность имени.

Т.е., вроде все как положено. Но, интересное начинается потом.
Теперь, нажмем кнопку Button1 для закрытия соединения. И, .... вместо нормального закрытия получаем исключение. Т.е. содержимое Memo1 станет таким:
Код

Before do invalid Execute
After do invalid Execute
ExecuteComplete esErrorsOccured: Ядро базы данных Microsoft Jet не может найти входную таблицу или запрос 'НесуществующаяТаблица'.  Проверьте существование таблицы или запроса и правильность имени.
Exeption on Close: Ядро базы данных Microsoft Jet не может найти входную таблицу или запрос 'НесуществующаяТаблица'.  Проверьте существование таблицы или запроса и правильность имени

Т.е., будет возбуждено исключение с результатом выполнения не заказанной операции (Close), а предыдущей асинхронной операции!
При повторном нажатии на Button1ADOConnection1 будет нормально закрыт.


ИТОГО.
Возникновение ошибки при асинхронном исполнернии SQL-оператора, ADO, запоминает это, и при первом следующем обращении возбуждает соответствующее исключение.
Так вот вопрос в том, как сделать так что бы после обработки ошибки в OnExecuteComplete я не получал этого исключения при последующем обращении к ADO?

P.S.
Особенно забавно получается если в приведенном выше тесте после нажатия на Button3 закрыть программу не нажимая на Button1. В этом случае в программе возникают утечки памяти. Это показывает что разработчики Delphi сами не расчитывали на подобный ход событий.



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
SergeBS
Дата 1.10.2007, 12:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22



Петрович
Цитата
Так вот вопрос в том, как сделать так что бы после обработки ошибки в OnExecuteComplete я не получал этого исключения при последующем обращении к ADO?

Например попробуй принудительно убить всю очередь команд:
Код

  except on e :Exception do
    Memo1.Lines.Add('Exeption on invalid Execute: '+e.Message);
    for i := (ADOConnection1.CommandCount – 1) downto 0 do
    begin
      ADOConnection1.Commands[i].Cancel;
      ADOConnection1.Commands[i].Free;
    end;
  end;

Цитата
Особенно забавно получается если в приведенном выше тесте после нажатия на Button3 закрыть программу не нажимая на Button1. В этом случае в программе возникают утечки памяти. Это показывает что разработчики Delphi сами не расчитывали на подобный ход событий.

Подозреваю, что все проще: пока у объекта не убита ошибочная ситуация - его не уничтожить. И пока не выполнена асинхронная операция - тоже.
Попробуй просто длительную, но правильную операцию запустить на выполнение и закрыть приложение до ее завершения. Скорее всего утечка тоже будет.  А потом она должна исчезнуть - по окончании операции. Если моя гипотеза верна.
PM MAIL   Вверх
Петрович
Дата 1.10.2007, 12:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(SergeBS @  1.10.2007,  13:32 Найти цитируемый пост)
Например попробуй принудительно убить всю очередь команд:

Я не совсем понял куда ты предлагаешь это вставить?

Я говорил о том, что уже после получения OnExecuteComplete с кодом (сообщением) ошибке, при попытке выполнить следующий, SQL-оператор я получу exception с докладом о предыдущем операторе.

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


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
SergeBS
Дата 1.10.2007, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22



Петрович
У тебя это:
Код

procedure TForm1.Button3Click(Sender: TObject);
begin
  Memo1.Clear;
  try  ADOConnection1.Close;  except  end;
  try
    Memo1.Lines.Add('Before do invalid Execute');
    ADOConnection1.Execute('DELETE FROM [НесуществующаяТаблица] WHERE CustNo<>CustNo',cmdText,[eoAsyncExecute]);
    Memo1.Lines.Add('After do invalid Execute');
  except on e :Exception do 
  begin
    Memo1.Lines.Add('Exeption on invalid Execute: '+e.Message);
//СЮДА:
    for i := (ADOConnection1.CommandCount – 1) downto 0 do
    begin
      ADOConnection1.Commands[i].Cancel;
      ADOConnection1.Commands[i].Free;
    end;
  end;
end;

Но проще - все в кучу, т.е. везде:
Код

  try
    ...
  except on e :Exception do
  begin
     ...
     MyException;
  end;
...

procedure MyException;
var
  i: integer
begin
  for i := (ADOConnection1.CommandCount – 1) downto 0 do
  begin
    ADOConnection1.Commands[i].Cancel;
    ADOConnection1.Commands[i].Free;
  end;
end;

Т.е. при любом исключении - грохается вся очередь выполнения.
Да, я это не проверял. Т.е. только предполагаю, что должно сработать. Дома - не забуду - попробую.
PM MAIL   Вверх
Петрович
Дата 1.10.2007, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(SergeBS @  1.10.2007,  15:30 Найти цитируемый пост)
Т.е. при любом исключении - грохается вся очередь выполнения.

smile
Блин. Похоже я не очень ясно объясняю...

Она и так грохается. О том что "она грохнулась" мне уже сообщили, передав в событие OnExecuteComplete даже сообщение об ошибке.

Попробую пояснить еще раз, слегка изменив постановку вопроса.

Работаю в асинхронном режиме.
Выполняю ДВА опреатора. Естественно последовательно, т.е. второй оператор запускается на исполнение только после получения события OnExecuteComplete о завершении выполнения первого.
Когда оба оператора нормально исполняются, то все хорошо.
Но, если при исполнении ПЕРВОГО оператора возникла ошибка (о чем мне сообщают в параметрах EventStatus и Error события OnExecuteComplete, то потом, когда на исполнение запускается ВТОРОЙ оператор, возникает exception, с тем-же  сообщением об ошибке (т.е. от первого оператора). 

Более того, можно даже не запускать второй SQL оператор, а просто например сказать Close для ADOConnection1, и в ответ получить исключение: ''Нет таблицы ....."

Т.е., типа кто-то (один из модулей программы) неудачно выполнил запрос, а потом кто-то другой (другой модуль программы) в ответ на безобидный Close получает exception с совсем невразумительным сообщением!



--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
SergeBS
Дата 2.10.2007, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1111
Регистрация: 10.6.2005
Где: Владимир

Репутация: 11
Всего: 22



Петрович
Я невнятно изложил. Предлагаемыми cancel и free очищается вся очередь команд на выполнение в ADOconnection. Т.е. и ошибочная - тоже. Нет команд - нет exception. Вообще-то calcel для тебя не нужно. Только для унификации - чтобы навесив на кнопку процедуру MyException можно было в любой момент прервать выполнение всего подряд.
PM MAIL   Вверх
Петрович
Дата 2.10.2007, 11:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Да я понимаю что такое очистка очереди команд!
Но, во первых, в момент возникновения события OnExecuteComplete никакой очереди уже не существует - запрос исполнен (удачно или не удачно)!
Во вторых, туда, куда ты предлагаешь вставить код мы вообще никогда не попадаем! Речь идет об асинхронном исполнении запросов. Т.е., когда делается:
Код

ADOConnection1.Execute('DELETE FROM [НесуществующаяТаблица] WHERE CustNo<>CustNo',cmdText,[eoAsyncExecute]);

исключения не возникает - запрос лишь отправляется на исполнение, и еще не известно что он содержит ошибку.

Это сообщение отредактировал(а) Петрович - 2.10.2007, 11:41


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
Петрович
Дата 3.10.2007, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Ха!
Тут на всякий случай все же заглянул на то что такое свойство Commands которым мне тут предлагали воспользоваться....
Выяснилось, к обсуждаемой теме оно вообще не имеет никакого отношения!!!!

В общем, я так понял, среди посетителей форума нет программеров использующих асинхронное исполнение запросов  smile 

В общем, буду использовать пока найденное мною решение (которое мне не нравится). Оно заключается в том, что бы в обработчике OnExecuteComplete, если получен код завершения с ошибкой, вызывать обращение к объекту ADO, с игнорированием exception. 
Т.е. получается что-то вроде такого:
Код

 procedure TForm1.ADOConnection1ExecuteComplete(Connection: TADOConnection;
  RecordsAffected: Integer; const Error: Error; var EventStatus: TEventStatus;
  const Command: _Command; const Recordset: _Recordset);
begin
  case EventStatus  of
    esOK            : Memo1.Lines.Add('ExecuteComplete esOK ('+IntToStr(RecordsAffected)+')');
    esErrorsOccured : begin
        Memo1.Lines.Add('ExecuteComplete esErrorsOccured: '+Error.Description);
        try
          if  ADOConnection1.State = []  then  ;
        except
        end;
      end;
    esCantDeny      : Memo1.Lines.Add('ExecuteComplete esCantDeny');
    esCancel        : Memo1.Lines.Add('ExecuteComplete esCancel');
    esUnwantedEvent : Memo1.Lines.Add('ExecuteComplete esUnwantedEvent');
    else              Memo1.Lines.Add('ExecuteComplete unknown '+IntToStr(Ord(EventStatus)));
  end;
  EventStatus := esUnwantedEvent;
end;

Тогда, если Execute завершился неудачей, то чтение статуса вызовет exception который будет благополучно проглочен.

Однако, столкнулся с еще одной проблемкой  smile 
Если вызвать ADOConnection1.Close сразу из обработчика ADOConnection1ExecuteComplete то программа вообще "зависает" наглухо! Т.е. управление уходит в библиотеку ADO и из нее уже не возвращается!

В общем, бардак да и только.   smile 

Хотя, весь мой жизненный опыт подсказывает что это все таки наверное я что-то делаю некорректно.

Может кто-то хоть посоветует куда заглянуть за примерами работы в асинхронном режиме с ADO ?


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 4.10.2007, 08:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Петрович, не а если посмотреть что в это врема передоется к базе и обратно? имею в виду просмотреть в профаилере.
почему то складывется впечетление что после неудачного завершения, при следуиших деиствиах (в данном случае перед закритием)  ADOConnection пытается снова выполнить старыи запрос (чтоб не остатся в долгу).
Цитата(Петрович @  3.10.2007,  15:14 Найти цитируемый пост)
Если вызвать ADOConnection1.Close сразу из обработчика ADOConnection1ExecuteComplete то программа вообще "зависает" наглухо!
тут по моему нечего удивительного, он не может сам себе харакири сделать. 
вопрос правда интересный, но делфиа нет, и сам проверить не могу.
PM MAIL   Вверх
Петрович
Дата 5.10.2007, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(kobra @  4.10.2007,  09:48 Найти цитируемый пост)
складывется впечетление что после неудачного завершения, при следуиших деиствиах (в данном случае перед закритием)  ADOConnection пытается снова выполнить старыи запрос (чтоб не остатся в долгу).

Угу. А ему не кажется что он за меня что-то решает? Такого быть не должно. Т.к. получив от него ошибку я уже мог предпринять некоторые 
ответные действия (например подготовить к запуску ядерную ракету  smile ). 
И вообще, у нормальной программы мозги могут в трубочку свернуться когда на обращение к свойству State, она получает исключение с кодом и сообщением "Ядро базы данных Microsoft Jet не может найти входную таблицу или запрос 'НесуществующаяТаблица'.  Проверьте существование таблицы или запроса и правильность имени."

А если серьезно, то трассировка по коду модулей дельфи приводит к тому что я вижу что при обращении к COM-объекту вываливается ошибка. Что еще трассировать я не знаю smile
Кроме того, в рабочем проекте, ошибку у меня вызывает запрос требующий экслюзивного доступа к БД. Собственно она и возникает потому что БД открыта другим процессом. Так вот, пред тем как она возникает, ADO ожидает некоторое время (типа вдруг освободят). Соответственно, реальная попытка выполнить занимает около 15-сек. А вот при втором обращении (после обнаружения), exception возникает практически мгновенно.


Цитата(kobra @  4.10.2007,  09:48 Найти цитируемый пост)
тут по моему нечего удивительного, он не может сам себе харакири сделать.

В принципе я его понимаю. Однако, не все так просто.
Если даже сделать так:
  • 1 В обрабочике OnExecuteComplete я Post'ом посылаю своему главному окну специальное сообщение и завершаю обработчик.
  • 2 В обработчике этого специального сообщения (т.е. ужа за пределами OnExecuteComplete), я вызываю Close.

В результате, все равно получаю висяк  smile .

Нормально срабатывает если делаю так:
  • 1 В обрабочике OnExecuteComplete я Post'ом посылаю своему главному окну первое специальное сообщение завершаю обработчик.
  • 2 В обработчике перовго специального сообщения я вновь Post'ом посылаю своему главному окну второе специальное сообщение
  • 3 В обработчике второго специального сообщения я вызываю Close.

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

Хотя, теперь у меня таки получился код асинхронно выполняющий SQL-скрипт smile. Правда, когда я вот-так как здесь выяснял некоторые тонкости повдения опытным путем а не по описанию, меня гложат сомнения в проавильности работы моего кода в разных ситуациях.
Но, пока выбора нет.


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 7.10.2007, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Цитата(Петрович @  5.10.2007,  15:22 Найти цитируемый пост)
Кроме того, в рабочем проекте, ошибку у меня вызывает запрос требующий экслюзивного доступа к БД. Собственно она и возникает потому что БД открыта другим процессом. Так вот, пред тем как она возникает, ADO ожидает некоторое время (типа вдруг освободят). Соответственно, реальная попытка выполнить занимает около 15-сек. А вот при втором обращении (после обнаружения), exception возникает практически мгновенно.
потому я и просил посмотреть профаилер (к mssql подклучи). т.е. трасировать не в делфи а обращение к базе. если второи раз сообшение вылетает моментально, наверняка обращение к базе уже не происходит. значит при первой неудавшеися попытке нужно сделать чтото, что коректно освободит какоито ресурс, или сбросит флаг, или . . .. но какои, даже не догадывюс. 
Цитата(Петрович @  5.10.2007,  15:22 Найти цитируемый пост)
И вообще, что-то мне не удалось найти реальных примеров использования асинхронного исполнения запросов.
пару лет назад я тоже пытался исползовать асинхронные запросы, но появилис какието непонятные проблемы, правда тепер не помню какие. помучавщис пару дней, и не наидя ответов, забросил.
правда мне очен странным кажется вот что
Цитата(Петрович @  5.10.2007,  15:22 Найти цитируемый пост)
1 В обрабочике OnExecuteComplete я Post'ом посылаю своему главному окну специальное сообщение и завершаю обработчик.
2 В обработчике этого специального сообщения (т.е. ужа за пределами OnExecuteComplete), я вызываю Close. 
если ты уверен что обработчик OnExecuteComplete после отправки Post-а завершается, то может попробуеш такои вариант.

1. В обрабочике OnExecuteComplete я Post'ом посылаю своему главному окну специальное сообщение и завершаю обработчик.
2. В обработчике этого специального сообщения (т.е. ужа за пределами OnExecuteComplete), запустить таимер, хота бы на пару секунд.
3. таимер вызывает Close. 

или же прямо из OnExecuteComplete запустить таимер.

но в лубом случае, проблема останется, так как проблема реално состоит в правилной обработке исклучения.
PM MAIL   Вверх
Петрович
Дата 7.10.2007, 17:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(kobra @  7.10.2007,  14:03 Найти цитируемый пост)
если ты уверен что обработчик OnExecuteComplete после отправки Post-а завершается, то может попробуеш такои вариант.

1. В обрабочике OnExecuteComplete я Post'ом посылаю своему главному окну специальное сообщение и завершаю обработчик.
2. В обработчике этого специального сообщения (т.е. ужа за пределами OnExecuteComplete), запустить таимер, хота бы на пару секунд.
3. таимер вызывает Close. 


Пробовал - нормально. И это понятно. Срабатывание таймера, это правтически адекватно моему второму сообщению. Более того, я почти таким способом и "нащупал" способ со вторым сообщением.


Цитата(kobra @  7.10.2007,  14:03 Найти цитируемый пост)
но в лубом случае, проблема останется, так как проблема реално состоит в правилной обработке исклучения. 

Не, проблема "необходимости двойного сообщения" никак не связана с ошибкой исполнения запроса. Она проявляется даже если все асинхронные запросы выполнинилсь без ошибок.


Цитата(kobra @  7.10.2007,  14:03 Найти цитируемый пост)
пару лет назад я тоже пытался исползовать асинхронные запросы, но появилис какието непонятные проблемы, правда тепер не помню какие. помучавщис пару дней, и не наидя ответов, забросил.

smile Я оказался терпеливее - я таки добился полноценной работы, хоть и не совсем понятным способом ;)


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
kobra
Дата 8.10.2007, 08:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 730
Регистрация: 15.6.2005
Где: Грузия, Тбилиси

Репутация: 1
Всего: 9



Цитата(Петрович @  7.10.2007,  17:49 Найти цитируемый пост)
 Я оказался терпеливее - я таки добился полноценной работы, хоть и не совсем понятным способом ;) 
с чем вас и поздравляю smile 
но буть остарожен, не люблю я когда не понемаю как код работает.
удачи

PM MAIL   Вверх
vinvin
Дата 8.10.2007, 14:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 35
Регистрация: 30.1.2007

Репутация: нет
Всего: 1



А зачем непременно связываться с асинхронными запросами? 
Ну если не работает или непонятно как работает - можно обойти проблему с помощью создания потока (TThread). 
Создай поток, закинь на исполнение в нем команды в синхронной обработке, там же и обработку ошибок. И проблем, как мне кажется, будет меньше, да и решение проще.
PM MAIL   Вверх
Петрович
Дата 18.10.2007, 12:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: 6
Всего: 55



Цитата(vinvin @  8.10.2007,  15:37 Найти цитируемый пост)
Создай поток, закинь на исполнение в нем команды в синхронной обработке, там же и обработку ошибок. И проблем, как мне кажется, будет меньше, да и решение проще. 

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


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

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


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.1005 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.