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

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

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

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

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

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


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


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

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

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



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

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

Откуда:
Сообщений: 9657
Попробуй заменить тело метода на:
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

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

Откуда: г. Екатеринбург
Сообщений: 499
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

Откуда: г. Екатеринбург
Сообщений: 499
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
Сообщений: 6281
я совсем не в теме, просто проходил мимо :) и заметил, что как то странно используется имя класса. Удивлен, что это вообще скомпилировалось

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

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

Откуда: СПб --> Dortmund
Сообщений: 6281
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

Откуда: г. Екатеринбург
Сообщений: 499
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

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

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

Откуда: г. Екатеринбург
Сообщений: 499
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

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

{-------------------------------------------------------------------------------}
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

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

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


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

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


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


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

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

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

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

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

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

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
Сообщений: 6281
                 ## 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

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

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
Сообщений: 6281
Мимопроходящий
Complete versus short-circuit Boolean evaluation


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

но зато другое нашлось: если это включено {$B+}, то тогда только держись
9 окт 18, 16:43    [21699482]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6281
P.S.
http://delphimaster.net/view/1-10818
9 окт 18, 16:44    [21699483]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Кроик Семён
Member

Откуда: СПб --> Dortmund
Сообщений: 6281
P.S.
спасибо короче, главное увидел в написанном виде
9 окт 18, 16:48    [21699487]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Мимопроходящий
Member

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

09.10.2018 16:43, Кроик Семён пишет:
> в доке этого нет (D6 german)

это было и есть всегда.
проверил в справке к D5
Complete Boolean Evaluation

Posted via ActualForum NNTP Server 1.5

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

Откуда: г. Екатеринбург
Сообщений: 499
Кроик Семён
                 ## 1 ##                           ## 2 ##
while (FWaitThread <> nil) and (FWaitThread.ThreadID <> TThread.Current.ThreadID) do


Kстати, нигде не смог найти в доке, но опытным путем заметил (Delphi 6), что второе условие не будет даже проверятся, если первое FALSE.
И всвязи с этим не знаю, всегда ли такое поведение. Есть ли 100%-ая гарания этой последовательности выполнения.
Ведь если нет, то возможен вызов FWaitThread.ThreadID даже если FWaitThread=nil.


По логике, если FWaitThread = nil и оно стоит вторым, то как раз таки, будут ошибки памяти т.к. идёт обращение к потоку, если оно стоит первый и равно nil то второе условие не будет проверяться, а будет проигнорировано
9 окт 18, 17:03    [21699500]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
Кроик Семён
                 ## 1 ##                           ## 2 ##
while (FWaitThread <> nil) and (FWaitThread.ThreadID <> TThread.Current.ThreadID) do


Kстати, нигде не смог найти в доке, но опытным путем заметил (Delphi 6), что второе условие не будет даже проверятся, если первое FALSE.
И всвязи с этим не знаю, всегда ли такое поведение. Есть ли 100%-ая гарания этой последовательности выполнения.
Ведь если нет, то возможен вызов FWaitThread.ThreadID даже если FWaitThread=nil.

Открой свойства проекта и нажми F1:
Complete boolean eval
Switches between the two different models of Delphi code generation for the AND and OR Boolean operators. When enabled (equivalent to {$B+}), the compiler generates code for complete Boolean expression evaluation. This means that every operand of a Boolean expression built from the AND and OR operators is guaranteed to be evaluated, even when the result of the entire expression is already known. When disabled (equivalent to {$B-}), the compiler generates code for short-circuit Boolean expression evaluation, which means that evaluation stops as soon as the result of the entire expression becomes evident in left to right order of evaluation.


К сообщению приложен файл. Размер - 49Kb
9 окт 18, 17:45    [21699551]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
X-Cite
Member

Откуда: Минск
Сообщений: 1203
Мимопроходящий
09.10.2018 16:10, X-Cite пишет:
> Так оформите в QC

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

Сказанное в слух - будет забыто и забито.
Положенное на бумагу - будет мозолить глаза.
9 окт 18, 18:11    [21699582]     Ответить | Цитировать Сообщить модератору
 Re: FireDAC зависает при разрыве соединения.  [new]
Dmitry Arefiev
Member

Откуда:
Сообщений: 9657
X-Cite
Сказанное в слух - будет забыто и забито.
Положенное на бумагу - будет мозолить глаза.

+3
9 окт 18, 18:26    [21699591]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2      [все]
Все форумы / Delphi Ответить