Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 FireDAC зависает при разрыве соединения.  [new]
Однорукий ламер
Member

Откуда: Санкт-Петербург
Сообщений: 74
Добрый день, коллеги.

Помогите плиз решить задачку, уже голову сломал.

Приложение работает с БД на MS SQL Server.

Использую два коннекта. Первый для работы с данными. Второй для подписки к ServiceBroker через FDEventAlert.
Все бы ничего, и в штатном режиме все работает и закрывается корректно.
НО при разрыве соединения (тупо выдергиваю сетевой шнурок) при попытке закрыть приложение Второй коннект зависает и не дает завершиться приложению. Помогает только снятие задачи через диспетчер.

Дата модуль с элементами FireDAC создается динамически.
При закрытие главной формы пытаюсь сделать Datamodule.Destroy - зависает.
Пытаюсь руками закрыть коннект Connect2.Connected := false - зависает.
Так же FDEventAlert.Unregister - зависает.

Что еще можно попробовать, что бы корректно завершить приложение при разрыве соединения?
3 авг 17, 11:02    [20697247]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1136
Попробуйте.
FDConnection.AbortJob();
3 авг 17, 22:18    [20699205]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1136
Есть подозрение что зависает вот тут:
Пройдите отладчиком, посмотрите
FireDAC.Stan.Util
procedure TFDThread.Execute;
....
case FMessageEvent.WaitFor(FIdleTimeout) of
...
3 авг 17, 22:24    [20699214]     Ответить | Цитировать Сообщить модератору
Между сообщениями интервал более 1 года.
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
Добрый день.

Проблема точь в точь!

Долго не мог понять в чём проблема, и она проявилась после того как сделал перевод проекта в XE6 на DX10.2.


X-Cite
Попробуйте.
FDConnection.AbortJob();


Это не помогает(((
Помогите, что ещё можно попробовать?
8 окт 18, 14:40    [21698158]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
cptngrb
Member

Откуда:
Сообщений: 196
Игорь_UUS,
AutoConnect:= False;
AutoReconnect:= False;
8 окт 18, 17:14    [21698420]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
cptngrb
Игорь_UUS,
AutoConnect:= False;
AutoReconnect:= False;



теперь пишет ошибку "Must by active" на

FEventAlerter.Register
8 окт 18, 17:39    [21698440]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9589
Попробуй заменить тело метода на:
procedure TFDPhysMSSQLEventAlerter.InternalAbortJob;
begin
  if FWaitThread <> nil then begin
    FWaitThread.Terminate;
    FWaitCommand.AbortJob(True);
    while (FWaitThread.ThreadID <> TThread.Current.ThreadID) and (FWaitThread <> nil) do
      Sleep(1);
  end;
end;
8 окт 18, 21:51    [21698686]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
bk0010
Member

Откуда:
Сообщений: 4618
Dmitry, скажите, вы сейчас поддерживаете FireDAC или "Изя все"? Или в Дебаркадере кто-то его пилит вместо вас?
8 окт 18, 22:25    [21698725]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
Dmitry Arefiev
Попробуй заменить тело метода на:
procedure TFDPhysMSSQLEventAlerter.InternalAbortJob;
begin
  if FWaitThread <> nil then begin
    FWaitThread.Terminate;
    FWaitCommand.AbortJob(True);
    while (FWaitThread.ThreadID <> TThread.Current.ThreadID) and (FWaitThread <> nil) do
      Sleep(1);
  end;
end;


Dmitry ВЫ БОГ!!!! Огромное спасибо!!!

Помогло, единственное не разобрался как перекомпилить исходники пакета ((. Файл данного юнита скопировал в папку с проектом, внёс корректировки... получается при компиляции, среда его подхватывает (а не тот, который лежит в директории delphi) и работа идёт уже с ним
9 окт 18, 10:02    [21698927]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
Dmitry Arefiev,

Только обрадовался, но не тут то было.

Если в процессе работы произошло разъединение с БД, программа не залипает, и восстанавливает соединение корректно.
Но, когда начинаешь закрывать приложение появляется "access violation at address..."

Пробовал "и так и эдак", и уничтожал объект "EventAlerter" и создавал заново после разрыва... всё равно ошибка памяти лезет. Видимо поток созданный в EventAlerter "висит"(( и выход в "InternalAbortJob"

procedure TFDPhysMSSQLEventAlerter.InternalAbortJob;
begin
  if FWaitThread <> nil then begin
    FWaitThread.Terminate;
    FWaitCommand.AbortJob(True);
    while (FWaitThread.ThreadID <> TThread.Current.ThreadID) and (FWaitThread <> nil) do
      Sleep(1);
  end;
end;


всё же не корректен.

Что можно ещё попробовать?
9 окт 18, 10:52    [21698975]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6251
я совсем не в теме, просто проходил мимо :) и заметил, что как то странно используется имя класса. Удивлен, что это вообще скомпилировалось

while (FWaitThread.ThreadID <> TThread.Current.ThreadID) and
9 окт 18, 11:25    [21699023]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6251
P.S.
если Current(), конечно, не классовая функция ....
9 окт 18, 11:31    [21699031]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6251
P.P.S.

Aaaa
http://docwiki.embarcadero.com/Libraries/Tokyo/en/System.Classes.TThread.Current

class property Current: TThread read GetCurrentThread;


ОК, не обращайте внимание на все мои 3 поста
9 окт 18, 11:38    [21699042]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
procedure TFDPhysMSSQLEventThread.Execute;
begin
  FAlerter.RegisterNotifications();
  while not Terminated and FAlerter.IsRunning do
    try
      if FAlerter.FMessageTab.Columns.Count = 0 then
        FAlerter.FWaitCommand.Define(FAlerter.FMessageTab);
      FAlerter.FWaitCommand.Open();                 <-- Заходит и вечно висит, если возникла ошибка (я так полагаю любая)
      if not Terminated then begin
        FAlerter.FWaitCommand.Fetch(FAlerter.FMessageTab, True);
        if (FAlerter.FMessageTab.Rows.Count > 0) and
           FAlerter.ProcessNotifications() then
          FAlerter.RegisterNotifications();
      end;
    except
      on E: EFDDBEngineException do begin
        Terminate;
        if not (E.Kind in [ekCmdAborted, ekServerGone]) then
          FAlerter.AbortJob;
      end;
    end;
end;


Если указать в свойстве TFDEventAlerter.Options.Timeout что-то более "0", то FAlerter.FWaitCommand.Open() будет жить именно это время в милисекундах. Но если возникает ошибка разъединения, данный метод залипает и следовательно поток остаётся жив!
Ошибка видна только под дебагом, следовательно она находится "где-то" под try except end, и далее что-то идёт не так как штатно.

Из за того, что поток остаётся жив, я предполагаю именно из-за этого возникает ошибка памяти по завершению приложения((
9 окт 18, 12:05    [21699099]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9589
Игорь_UUS

(FWaitThread.ThreadID <> TThread.Current.ThreadID) and (FWaitThread <> nil)
Условия нвадо поменять местами ....
9 окт 18, 12:22    [21699134]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
Dmitry Arefiev
Игорь_UUS

(FWaitThread.ThreadID <> TThread.Current.ThreadID) and (FWaitThread <> nil)
Условия нвадо поменять местами ....


Поменял, помогло на 50%

Из procedure TFDPhysMSSQLEventThread.Execute стал выходить... но вот ошибка памяти по каким то причинам осталась((, но вот только под дебагом. При этом ошибка не лезет наружу, если запуска не под дебагом
9 окт 18, 13:20    [21699195]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
По коду получилось вот так:

{-------------------------------------------------------------------------------}
procedure TFDPhysMSSQLEventAlerter.InternalAbortJob;
begin
  if FWaitThread <> nil then begin
    FWaitThread.Terminate;
    FWaitCommand.AbortJob(True);
    while (FWaitThread <> nil) and (FWaitThread.ThreadID <> TThread.Current.ThreadID) do
      Sleep(1);
  end;
end;


я полагаю как надо...
9 окт 18, 13:29    [21699213]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1136
Игорь_UUS

Из procedure TFDPhysMSSQLEventThread.Execute стал выходить... но вот ошибка памяти по каким то причинам осталась((, но вот только под дебагом. При этом ошибка не лезет наружу, если запуска не под дебагом


Настройка компилятора "Complete boolean evaluation" должна быть False и в Debug и в Release
9 окт 18, 14:24    [21699311]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
X-Cite
Игорь_UUS
Из procedure TFDPhysMSSQLEventThread.Execute стал выходить... но вот ошибка памяти по каким то причинам осталась((, но вот только под дебагом. При этом ошибка не лезет наружу, если запуска не под дебагом


Настройка компилятора "Complete boolean evaluation" должна быть False и в Debug и в Release


И там и там всегда в False
9 окт 18, 14:31    [21699321]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Игорь_UUS
Member

Откуда: г. Екатеринбург
Сообщений: 483
После двухдневных "танцев с бубном" это хоть как то стало работать(((. Под "хоть как то" явно на настылях, что-то внутри работает не правильно.

while (FWaitThread <> nil) and (FWaitThread.ThreadID <> TThread.Current.ThreadID) do


Данная "подпилка" действительно помогает избежать залипания программы при разрыве связи, но под демагогом лезут ошибки памяти при завершении работы программы, или если в процессе работы вызвать:

FEventAlerter.Unregister;


Если же оставить по старому:
procedure TFDPhysMSSQLEventAlerter.InternalAbortJob;
begin
  if FWaitThread <> nil then begin
    FWaitThread.Terminate;
    FWaitCommand.AbortJob(True);
    while FWaitThread <> nil do
      Sleep(1);
  end;
end;


работает стабильно (имеется ввиду без ошибок памяти) хоть под дебагом хоть просто запускай, НО программа обязательно залипнет как только произойдёт сбой связи с базой данных.

В компоненте "TFDEventAlerter" 100% есть баг, и его похоже не было в Delphi XE6. Могу судить по тому, как только перешли на Delphi DX10.2, и установив эту сборку клиентам, периодический поступают жалобы о залипании программы ИМЕННО после потери связи с сервером.

Остаётся надеяться, что данный "костыль" не будет усугублять проблему в собранном проекте...
9 окт 18, 14:46    [21699347]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1136
Игорь_UUS,

Так оформите в QC
9 окт 18, 16:10    [21699454]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 29168

09.10.2018 16:10, X-Cite пишет:
> Так оформите в QC

а смысл?
он же с автором общался.

Posted via ActualForum NNTP Server 1.5

9 окт 18, 16:15    [21699459]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6251
                 ## 1 ##                           ## 2 ##
while (FWaitThread <> nil) and (FWaitThread.ThreadID <> TThread.Current.ThreadID) do


Kстати, нигде не смог найти в доке, но опытным путем заметил (Delphi 6), что второе условие не будет даже проверятся, если первое FALSE.
И всвязи с этим не знаю, всегда ли такое поведение. Есть ли 100%-ая гарания этой последовательности выполнения.
Ведь если нет, то возможен вызов FWaitThread.ThreadID даже если FWaitThread=nil.
9 окт 18, 16:22    [21699465]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Мимопроходящий
Member

Откуда: бурятский тундрюк, эсквайр
Сообщений: 29168

09.10.2018 16:22, Кроик Семён пишет:
> Kстати, нигде не смог найти в доке,

да ты уху ел.
F1: Complete versus short-circuit Boolean evaluation

Posted via ActualForum NNTP Server 1.5

9 окт 18, 16:24    [21699466]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6251
Мимопроходящий
Complete versus short-circuit Boolean evaluation


в доке этого нет (D6 german)

но зато другое нашлось: если это включено {$B+}, то тогда только держись
9 окт 18, 16:43    [21699482]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить