NonBlocking, AfterFetch

Обсуждение возникших проблем, предложений и ошибок ODAC компонентов
Закрыто
Lein
Сообщения: 3
Зарегистрирован: Ср 13 мар 2013 20:56

NonBlocking, AfterFetch

Сообщение Lein » Ср 13 мар 2013 21:01

Мне желательно выполнять запрос типа SELECT в дополнительном потоке, а затем обработать полученные

данные в основном потоке программы.
Я выполняю действия по схеме следующего примера:

Код: Выделить всё

  OraQuery1.SQL.Text := 'select 1 from dual';
  OraQuery1.NonBlocking := true;
  OraQuery1.FetchAll := True;
  OraQuery1.Open;
procedure TForm1.OraQuery1AfterFetch(DataSet: TCustomDADataSet);
begin
  //Accert(DataSet.Eof and DataSet.Bof and (DataSet.RecordCount>0))
  while (not OraQuery1.Eof) do
  begin
    -- обработка данных
  end;
end;

Однако часто при обработке события AfterFetch DataSet находится в некорректном состоянии":
DataSet.Eof and DataSet.Bof and (DataSet.RecordCount>0)
Данные существует, их количество больше нуля, но обработать их невозможно.
Ситуация возникает случайно, вероятность ее велика, даже на самых простых запросах, например,
select 1 from dual

Описанные явления я наблюдал в средах:
  • Delphi 5, Delphi 7,
    Oracle Client 9, Oracle Client 10
    Oracle Server 10
    Odac 8.6.12
Что я делаю, не так?
Как следует решать описанную задачу?
В компоненте TOraQuery ошибка?

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: NonBlocking, AfterFetch

Сообщение Alexp » Чт 14 мар 2013 12:05

Hello,

В момент события AfterFetch DataSet еще не инициализирован, это событие сигнализирует о том что закончилось физическое чтение данных с сервера. Мы планируем добавить такое событие в одной из следующих версий ODAC

Lein
Сообщения: 3
Зарегистрирован: Ср 13 мар 2013 20:56

Re: NonBlocking, AfterFetch

Сообщение Lein » Чт 14 мар 2013 21:06

Спасибо, это было бы хорошо!
Можно ли в настоящей версии ODAC определить, каким-либо образом, инициализирован ли Dataset, например, по таймеру?
Безопасно ли использовать до инициализации визуальные компоненты, например, гриды, соединенные с Dataset с помощью DataSource?
Безопасно ли вызывать до инициализации стандартные методы TDataset (First, Next, FieldByName и т.д.)?
У меня при обработке AfterFetch иногда зависает программа и я пытаюсь понять причины.

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: NonBlocking, AfterFetch

Сообщение Alexp » Пт 15 мар 2013 12:59

Добрый день,

В данный момент определить окончание запроса можно например следующим образом

Код: Выделить всё

procedure TForm1.Button1Click(Sender: TObject);
begin
  Timer1.Enabled := True;
  OraQuery1.Open;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  if (not OraQuery1.Executing) and  (not OraQuery1.Fetching) then
  begin
    //----
    timer.Enabled := false;
  end;
end;
Да вы можете использовать DBGrid с таким DataSet, пример демонстрирующий это поведение находиться в папке Query в демо примерах

Lein
Сообщения: 3
Зарегистрирован: Ср 13 мар 2013 20:56

Re: NonBlocking, AfterFetch

Сообщение Lein » Вс 07 апр 2013 18:56

Мне кажется, что иногда бывает состояние, когда выполняется условие
(not OraQuery1.Executing) and (not OraQuery1.Fetching)
and OraQuery1.Eof and OraQuery1.Bof and (OraQuery1.RecordCount>0),
но я могу ошибаться, событие регулярно не повторяется.
Но я нашел условия, при котором программа регулярно зависает в режиме NonBlocking!
Условия очень просты:
  • На форме расположены OraQuery, OraDataSource, DBGrid
    FetchAll = True; NonBlocking = True
    DBGrid достаточно велик, в нем отображается записей больше, чем OraQuery.FetchRows (по умолчанию 25)
    В результате запроса SELECT количество записей также больше, чем FetchRows.
После выполнения OraQuery.Open программа зависает!

Код: Выделить всё

procedure TForm1.Button4Click(Sender: TObject);
begin
  OraQuery1.Close;
  OraQuery1.SQL.Text := 'select level from dual connect by level < 27';
  OraQuery1.FetchAll := True;
  OraQuery1.NonBlocking := True;
  OraQuery1.Open;
end;
В стандартном демо примере OdacDemo, если выбрать Demo Query,
установить флаги NonBlocking, FetchAll,
установить текст запроса
select * from user_objects where rownum < 27
или
select level from dual connect by level < 27
и нажать кнопку Open,
Демо пример зависнет.

Описанную ошибку я наблюдал в средах:
Delphi 5, Delphi 7, Delphi 2006
Odac 8.6.12
Oracle Client 9, Oracle Client 10
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0
Windows XP

Alexp
Devart Team
Сообщения: 349
Зарегистрирован: Пн 27 дек 2010 10:34

Re: NonBlocking, AfterFetch

Сообщение Alexp » Пн 08 апр 2013 09:49

Добрый день,

Спасибо за информацию, Мы воспроизвели проблему, и постараемся исправить ее в ближайшей версии ODAC

Закрыто