работу с базой затолкнуть в поток. Выборка то дело интересное. Может "сразу" ответ получить, а можно и "недельку" подождать.А теперь вопрос, что из этого надо помещать в отдельный поток?
о..чень надеюсь что это дело у вас хотя бы в потоке а не со всякими антифризами....Эта программа (далее ПР) получает сообщение от службы которая считывает события с АТС и рассылает по экземплярам ПР на разных рабочих местах сообщение по TCP
Для этого используются компоненты Indy10
Статистика: Добавлено pupsik — 21.01.2021 16:06:06
Статистика: Добавлено haword — 20.01.2021 14:03:04
Да, поэтому он не точен. Я сейчас не помню, но он точно синхронизируется с главым потоком либо через Synchronize или посылкой PostMessage.jsa писал(а):Запуск TTimer ..порождает отдельный поток TimerThread
он "тяжелый" и предназначен для "визуальных целей" - подсчитать время, сделать часики. Не точен, не монотонный, так как сильно заваязан на GUI. - точность падает с уменьшением интервала.jsa писал(а):почему TTimer не стоит использовать? В чем причина?
тем что 1) он выполняется вне программы, в ядре windows, отсюда более точен. 2) сделан так чтобы создания и завершения - был о вне программы, и таймер более легкий. Атомарен. ориентирован на мультимедиа, где выполняются жесткие требования по работе.jsa писал(а):Чем стандартный TTimer отличается от вашего варианта? не могу никак уловить это.
Статистика: Добавлено olegy123 — 19.01.2021 13:06:45
Статистика: Добавлено haword — 18.01.2021 14:13:40
olegy123 писал(а):TTimer.OnTime - в основе его находется TThread который PostMessage окну на котором он был создан. програ ловит сообщение из очереди и идет выполнять OnTime.
haword писал(а):но в чем прав так это в том что импользовать таймеры отстойно, надо потоки юзать и в них уже обработку делать а не в таймерах.
Статистика: Добавлено jsa — 18.01.2021 12:07:37
Статистика: Добавлено haword — 16.01.2021 18:01:09
jsa писал(а):Да это TTimer. Не знаю, что такое одноразовый таймер, но видимо это не он.
Код:
uses mmsystem;
procedure OnChange(Sender: TObject);
private
FTimerOnShot:Cardinal;
procedure TimerSearch(uTimerID, uMessage: UINT; dwUser, dw1, dw2: DWORD); stdcall;
begin
PostMessage(dwUser,WM_MyRefresh,0,0)
end;
procedure TForm1.OnChange(Sender: TObject);
begin
timeKillEvent(FTimerOnShot);
FTimerOnShot:=timeSetEvent(1000,1,@TimerSearch,Handle,TIME_ONESHOT);
end;Еще перегрузка главного потока, который необходим для взаимодействия с операционной системой.jsa писал(а):Влиять может частая избыточная перерисовка компонент окна. Так получается.
Статистика: Добавлено olegy123 — 15.01.2021 22:31:46
Статистика: Добавлено Seenkao — 15.01.2021 11:47:11
Статистика: Добавлено jsa — 15.01.2021 11:12:02
Seenkao писал(а):я уже задавал вопрос, а в этом вопросе и ответ.Seenkao писал(а):Посредством чего выводится изображение на экран?
Но, если используется LCL, то вероятно совпадают хендлы? (как это вообще возможно, если система сама присваивает им номера).
Seenkao писал(а):Возможны частые Sleep в программе (от них вообще в Windows лучше избавляться, если что-то критично по времени работы, так как это не стабильная задержка когда равна 1-й мс, может вылиться в 16 мс). Где-то цикл обработки, из которого нет выхода из-за каких-то случайно попавших туда данных. Где-то создание динамического массива, который не удаляется после того, как уже не нужен. Где-то излишний массив/данные, которые не используются, но при этом захламляют память.
Так же, возможна включена отладочная информация и/или включены флаги в отладочной информации, которые ломают работу программы (редкий случай для LCL и частый для прямого доступа).
Тут ни когда не угадаешь что у вас происходит.
Вы не предоставили ни чего! Абсолютно!
Где логи программы, которые должны выводиться, если вы отлаживаете свою программу?
вот вы ответили на свой вопрос, у вас в памяти работает цикл, который постоянно перерисовывает формы. А что это за цикл?jsa писал(а):но Lazarus продолжил тасовать окна проекта по циклу, не дорисовывая их.
да, может поможет, вероятно вы одну программу из другой запускаете и так по кругу и они пытаются друг друга отрисовать, а это и есть бесконечный цикл.
olegy123 писал(а):146% неправильный код. Который замедляет главный поток программы, он же в свою очеред не может ответить операционной системе на вызовы - та считает что програ подвисла.jsa писал(а):Спам через 5-10 минут примерно начинает вызывать подтормаживание второй программы на которую влияет ПР.
через 15-18 минут после старта спама вторая программа виснет, и в "Диспетчере задач" обозначена как "Не отвечает"
olegy123 писал(а):Что за Таймер? можно код? Если TTimer - то это зло, у него работа синхронизирована с главным потоком.
Таймер - одноазовый с изменяемой по времени отсрочкой активации?
Код:
procedure TFormCallCntr.FindPatWithPhoneExecute(Sender: TObject);
begin
LEditPhone.Text:=PhoneNum;
LEditFam.Text:=''; LEditFam.Font.Style:=[];
LEditIm.Text:=''; LEditIm.Font.Style:=[];
LEditOt.Text:=''; LEditOt.Font.Style:=[];
RButtonEMCpat.Checked:=false; RButtonEMCpat.Checked:=true;
end;
Код:
---про неправильную передачу параметров в текст запроса, просьба не комментировать, я вкурсе, еще не везде в проекте исправил
procedure TFormCallCntr.TimerFindPatTimer(Sender: TObject);
begin
TimerFindPat.Enabled:=false;
if RButtonEMCPat.Checked then
begin
Select_Pat.Close;
Select_Pat.SQL.Clear;
Select_Pat.SQL.Text:=Select_PatSQLText;
if (LEditFam.Text='') and (LEditIm.Text='') and (LEditOt.Text='') and (LEditPhone.Text='')
then Select_Pat.SQL.Add('where ID=0')
else begin
Select_Pat.SQL.Add('where isnull(Fam,'+#39+#39+') like '+#39+'%'+LEditFam.Text+'%'+#39);
Select_Pat.SQL.Add('and isnull(Im,'+#39+#39+') like '+#39+'%'+LEditIm.Text+'%'+#39);
Select_Pat.SQL.Add('and isnull(Ot,'+#39+#39+') like '+#39+'%'+LEditOt.Text+'%'+#39);
Select_Pat.SQL.Add('and isnull(Phone,'+#39+#39+') like '+#39+'%'+LEditPhone.Text+'%'+#39);
end;
Select_Pat.Open;
end;
FormCallCntr.ChangePatExecute(Sender); --- запуск выборки в двух других зависимых от Select_pat таблицах
end; olegy123 писал(а):нет SendMessage - заморозит работу.
olegy123 писал(а):Тут важно чтобы таймер сработал один раз и только после ввода последнего знака.
У меня есть пример, но покажу попоже.
olegy123 писал(а):jsa писал(а):Думаете, что общий проблемный ресурс тут видеопамять? Тогда почему только 2 программы, одна написанная на Lazarus и другая не Delphi имеют такие проблемы?
делфи/лазарус работает поверх системных вызовов, так что все кнопки поля ввода - это стандартные windows элементы. Если конечно не рисуете их самостоятельно в графике - канве или в OpenGL/DX.
olegy123 писал(а):У меня глюки были с любой серьезной программой если вместо нормальных дров стояли windows или стандартный VGA.
olegy123 писал(а):тогда понятно, там дефолтно идет драйвер режима VGA, нужно как минимум включать 2D режим.jsa писал(а):Win8 на виртуальной машине VirtualBox 5.2.28
olegy123 писал(а):Это VirtualBox? Значит нужны VirtualBox Guest Additions для Windows 10 там есть
"Выбор компонентов VirtualBox GuestAdditions для Windows 10. Вы можете выбрать поддержку ускорения 3D графики." Которой Windows 8/Windows 10 очень необходимы так как интерфейс весь написан на Direct2D.
Статистика: Добавлено jsa — 15.01.2021 08:32:43
Что за Таймер? можно код? Если TTimer - то это зло, у него работа синхронизирована с главным потоком.jsa писал(а):А вот callin_connect производит запись номера телефона в поле поиска в интерфейсе программы. После записи срабатывает событие OnChange в нем производится запуск таймера.
Таймер отсчитывает период задержки после ввода (сделано для того чтобы дать время пользователю набрать в поле поиска слово целиком).
нет SendMessage - заморозит работу. Тут важно чтобы таймер сработал один раз и только после ввода последнего знака.jsa писал(а):Возможно вместо PostMessage нужно использовать SendMessage .
jsa писал(а):Думаете, что общий проблемный ресурс тут видеопамять? Тогда почему только 2 программы, одна написанная на Lazarus и другая не Delphi имеют такие проблемы?
У меня глюки были с любой серьезной программой если вместо нормальных дров стояли windows или стандартный VGA.SSerge писал(а):так вот, достаточно часто после работы этой программы появлялся похожий эффект - либо любая программа на lazarus/delphi начинала запускаться с окном, в котором ничего не отрисовано, либо запускалась вглухую: висит где-то в памяти, а видимых окон нет. И так до перезагрузки операционной системы. Кстати, такое поведение было одним из весомых поводов прекратить писанину на лазарусе вообще.
тогда понятно, там дефолтно идет драйвер режима VGA, нужно как минимум включать 2D режим.jsa писал(а):Win8 на виртуальной машине VirtualBox 5.2.28
jsa писал(а):Думаю что причины те же.
https://yadi.sk/i/_EmEmjCbrOd2BQ
Статистика: Добавлено olegy123 — 14.01.2021 09:43:07
Статистика: Добавлено SSerge — 14.01.2021 09:05:10
Статистика: Добавлено haword — 13.01.2021 13:25:30
Seenkao писал(а):Всё свидетельствует, что захламляется видеопамять (возможно и общая память, что ещё хуже) делайте ллогирование. Отключайте части программ и смотрите что с собой несёт такую нагрузку.
В общем, проблема не описана и не было попытки её решить. (как я вижу)
Seenkao писал(а):Таймера? Каждый раз нового?
Статистика: Добавлено jsa — 13.01.2021 12:58:34
Статистика: Добавлено jsa — 13.01.2021 12:27:55
Снег Север писал(а):Мой хрустальный шар говорит, что самая вероятная причина - драйвер видеокарты на клиентском компе.
olegy123 писал(а):Такие фокусы могут быть когда окно(любое приложения, написанное на любом языке) не обрабатывает сообщения о перерисовке окна, или не успевает обработать все сообщения. простой бесконечный цикл, или наоборот блокировка главного потока может приводить к таким фокусам с перерисовкой.
Код:
//Обработка сигнала по TCP от службы ATEx
procedure TFormCallCntr.IdTCPServerATExExecute(AContext: TIdContext);
var strMsg, Callid, pn, cmd:string; p:integer;
begin
//Принимаем от клиента строку
cmd:=''; Sleep(10);
strMsg := AContext.Connection.Socket.ReadLn;
//Обработка
p:=pos('|',strMsg);
if p<>0 then
begin
//разделение полученной строки на ID звонка и номер телефона
cmd:=LowerCase(copy(strMsg,1,p-1)); //CallID:=copy(strMsg,1,p-1);
strMsg:=copy(strMsg,p+1,length(strMsg)-p);
p:=pos('|',strMsg);
if p<>0 then
begin
CallID:=copy(strMsg,1,p-1);
pn:=copy(strMsg,p+1,length(strMsg)-p); if pn<>'???' then PhoneNum:=pn;
end
else PhoneNum:=strMsg;
PhoneNum:=formatNumPhone( PhoneNum );
Sleep(10);
if cmd='callin_start' then PostMessage(Handle, Msg_PhoneVisible, 0, 0);
if cmd='callin_connect' then PostMessage(Handle, Msg_PhoneVisible, 1, 0);
if cmd='callin_stop' then PostMessage(Handle, Msg_PhoneVisible, 2, 0);
if cmd='callout_start' then PostMessage(Handle, Msg_PhoneVisible, 3, 0);
if cmd='callout_connect' then PostMessage(Handle, Msg_PhoneVisible, 4, 0);
if cmd='callout_stop' then PostMessage(Handle, Msg_PhoneVisible, 5, 0);
Sleep(10);
end;
end;
Код:
const
MessExePrm1=WM_USER;
MessExePrm2=WM_USER+1;
Msg_PhoneVisible=WM_USER+3;
....
private
{ private declarations }
procedure PhoneVisibleExec(var Msg: TMessage); message Msg_PhoneVisible;
procedure RangeDateChange(Sender: TObject);
procedure WMACT(var mes:TWMACTIVATE); message WM_ACTIVATE;
public
{ public declarations }
procedure ReadMessExePrm1(var MessExePrm1:TMessage); message MessExePrm1;
procedure ReadMessExePrm2(var MessExePrm2:TMessage); message MessExePrm2;
end;
Код:
//Переключение индикатора звонка телефона
procedure TFormCallCntr.PhoneVisibleExec(var Msg: TMessage);
var prm:integer;
begin
prm:=Msg.Wparam;
if prm=0 then //Включить индикатор телефона / Начало звонка DIAL_STATUS='callin_start'
begin
PanelPhone.Visible:=true;
ImagePhone.Visible:=false; ImageBtnInsertPhone.Visible:=true; ImageBtnOutPhone.Visible:=false;
LabelPhoneExternal.Font.Color:=clMaroon;
LabelPhoneExternal.Caption:='Вам звонят - '+PhoneNum;
TimerPhone.Interval:=100; TimerPhone.Enabled:=fl_flashing_phone_indicator;
end;
if (prm=1) or (prm=4) then //Включить индикатор телефона / Начало разговора DIAL_STATUS='connect'
begin
PanelPhone.Visible:=true;
ImagePhone.Visible:=true; ImageBtnInsertPhone.Visible:=false; ImageBtnOutPhone.Visible:=false;
LabelPhoneExternal.Font.Color:=clGreen;
if (prm=1) then LabelPhoneExternal.Caption:='Вы говорите с '+PhoneNum;
if (prm=4) then LabelPhoneExternal.Caption:='Вы дозвонились - '+PhoneNum;
TimerPhone.Interval:=0; TimerPhone.Enabled:=false;
FormCallCntr.FindPatWithPhoneExecute(FormCallCntr);
end;
if (prm=2) or (prm=5) then //Выключить индикатор телефона / Звонок полностью окончен DIAL_STATUS:='stop'
begin
PanelPhone.Visible:=false;
TimerPhone.Interval:=0; TimerPhone.Enabled:=false;
SBtnCallout_start.Visible:=true;
end;
if prm=3 then //Включить индикатор телефона / Начало звонка DIAL_STATUS='callout_make'
begin
PanelPhone.Visible:=true;
ImagePhone.Visible:=false; ImageBtnInsertPhone.Visible:=false; ImageBtnOutPhone.Visible:=true;
LabelPhoneExternal.Font.Color:=clMaroon;
LabelPhoneExternal.Caption:='Вы звоните на номер '+LEditPhone.text;
TimerPhone.Interval:=100; FormCallCntr.TimerPhone.Enabled:=fl_flashing_phone_indicator;
end;
end;
В Indy имеется специальный компонент, который решает проблему замораживания
пользовательского интерфейса. Просто добавьте один компонент TIdAntiFreeze куда ни будь в
своем приложении, и вы сможете выполнять блокирующие вызовы без замораживания
пользовательского интерфейса. Использование TIdAntiFreeze позволяет получить все преимущества блокирующих сокетов, без
видимых недостатков.
Статистика: Добавлено jsa — 12.01.2021 12:19:09
Статистика: Добавлено jsa — 04.01.2020 17:06:35
Статистика: Добавлено jsa — 03.01.2020 06:30:25
Статистика: Добавлено sts — 25.12.2019 19:41:56
нужно смотреть на объем ОЗУ + своп.jsa писал(а):Но стоит их запустить обе, начинается трэш.
Статистика: Добавлено olegy123 — 25.12.2019 19:04:14
Статистика: Добавлено jsa — 25.12.2019 07:18:39