cro-logo      
Добро пожаловать, Гость. Пожалуйста, выберите Вход или Регистрация

 
 
  ГлавнаяСправкаПоискВходРегистрация  
 
Переключение на Главную Страницу Страниц: 1
Послать Тему Печать
Таймер и функция delete (Прочитано 1 076 раз)
Rasen
Бета-тестер
Вне Форума



Сообщений: 143
Таймер и функция delete
16.09.2021 :: 13:27:59
 
Кронос  7 версии. Решил переписать старый скрипт, добавить некоторые элементы. В частности, скрипт достаточно медленно работал, а в новой версии появилась возможность использовать фоновой поток. Да и в режиме автоматической обработки данных не было опции, которая позволила бы корректно прервать (остановить) работу скрипта. В новом скрипте решил использовать таймер. И возникла проблема. Скрипт то работал, то вылетал Кронос. Сначала никак не мог понять, в чем причина! Тестовый пример использования взят из хэлпа Луа. Старый скрипт, медленно, но работал. Потом, методом тыка, выявил причину возникновения ошибки. Это метод delete, класса Timer. Подтверждение этому - при крушении Кроноса создается новая запись в файле luacrash.log. Там указана причина: "Lua call stack  [C]: in function delete" и т.д.
Кстати, без него (delete),  скрипт нормально работает.
Кто-нибудь сталкивался с этой проблемой? Где-то я читал, что нужно обязательно освобождать память, занимаемую экземпляром объекта Timer, для этого и нужен этот метод.
Наверх
 
 
IP записан
 
Freelancer
Разработчик
Вне Форума


Per aspera ad Astra

Сообщений: 233
Re: Таймер и функция delete
Ответ #1 - 16.09.2021 :: 14:06:50
 
Покажите файлы luacrash.log и *.RPT если есть. И расскажите для чего примерно используется таймер, особенно если есть фоновые потоки.
Наверх
 
 
IP записан
 
Rasen
Бета-тестер
Вне Форума



Сообщений: 143
Re: Таймер и функция delete
Ответ #2 - 17.09.2021 :: 07:30:55
 
файлы в архиве. Версия банка - 4.
Фоновый поток пока не использую, но собираюсь. Таймер применяется для того, чтобы пользователь визуально мог отследить вывод текстовой информации о начале и окончании перебора записей.
Наверх
 

tmp.zip (2 KB | 32 )
 
IP записан
 
Zuluss
Бета-тестер
Вне Форума


Старинный пользователь
Кронос

Сообщений: 2 968
Санкт-Петербург
Re: Таймер и функция delete
Ответ #3 - 17.09.2021 :: 08:56:11
 
А фрагмент самого кода что ж не показали?
Используется таймер формы или глобальный?
Перед удалением таймер останавливаете?
timer:Stop()
timer:delete()
Наверх
 
 
IP записан
 
Freelancer
Разработчик
Вне Форума


Per aspera ad Astra

Сообщений: 233
Re: Таймер и функция delete
Ответ #4 - 17.09.2021 :: 11:19:03
 
Да, хорошо бы еще посмотреть на фрагмент кода.
Наверх
 
 
IP записан
 
Rasen
Бета-тестер
Вне Форума



Сообщений: 143
Re: Таймер и функция delete
Ответ #5 - 20.09.2021 :: 08:49:09
 
Пример тестового скрипта
Код:
local baseInfo, errStr 
local timer
local records -- объект RecordSet

--------------------  события ---------------------

function Форма_KeyPreview( event )
	if (event.Key == Keys.Escape) and (event.Type == FormKeyEvent.Pressed)
		then Форма_CloseForm()
	end
end

function Форма_CloseForm( form, event )
--timer:delete()
Me.self:CloseForm();  -- закрытие формы
end

function Форма_Open( form, event )
	return true 
end

function Форма_Load( form, event )
timer = Me:CreateTimer()   
baseInfo, errStr = CroApp.GetBank():GetBase("ДС"); 
end


--------------------  buttons -----------------------
function btLoadRefs_Click( control, event )

records = baseInfo:StringRequest("ОТ ДС01")  

Me.Text = "...Идет загрузка данных" 
Me:Redraw();
AddToList(Me.listRecords,records)
Me.Text = "данные загружены" 

timer:Start(2000);
timer.Tick = function (timer)
	Beep();
	Me.Text = "Число записей -" .. baseInfo.RecordsCount;
	timer:Stop()
end
end

--------------- functions ----------------

function AddToList (fList,fRecs)

	for rec in fRecs.Records do -- перебираем все записи набора
      fList:Add(rec:GetValue(3))
	end
end
 

Наверх
 
 
IP записан
 
Zuluss
Бета-тестер
Вне Форума


Старинный пользователь
Кронос

Сообщений: 2 968
Санкт-Петербург
Re: Таймер и функция delete
Ответ #6 - 20.09.2021 :: 10:15:36
 
Пока досконально не разбирался, но сразу видно, что эти строчки:
Код:
timer:Start(2000);
timer.Tick = function (timer)
	Beep();
	Me.Text = "Число записей -" .. baseInfo.RecordsCount;
	timer:Stop()
end 


некорректные.
У Вас еще не определена функция тела  таймера, а он уже запускается. Нужно наоборот.
Другой момент из области стиля именования. Если в форме используется глобальное имя timer, то внутри функции его лучше не использовать, а применить другое имя, например, tmr.
Таймер используется только при старте формы при заполнении списка записей. При этом сама функция перебора записей не включена в тело таймера, что неправильно.
Попозже попробуем смоделировать ситуацию.
Наверх
 
 
IP записан
 
Rasen
Бета-тестер
Вне Форума



Сообщений: 143
Re: Таймер и функция delete
Ответ #7 - 21.09.2021 :: 08:56:25
 
Цитата:
У Вас еще не определена функция тела  таймера, а он уже запускается. Нужно наоборот

В принципе, я Вашу логику понимаю, но я исходил из того, что интерпретатор сначала должен обработать "функцию тела таймера", а уж потом код внешней функции. Ну да ладно, я просто перенес старт таймера после timer.Tick. Ничего не поменялось, таймер работал. Потом подключил функцию delete() и скрипт "вылетел" с ошибкой. Закомментировал эту функцию, все нормально.
Потом поменял имя локальной переменной в "функции тела таймера". Но это то же ничего существенного не дало. Без timer:delete() скрипт работал, с ней - нет.

Цитата:
Таймер используется только при старте формы при заполнении списка записей. При этом сама функция перебора записей не включена в тело таймера, что неправильно

Нет, таймер в данном варианте кода используется только для того, чтобы вывести с задержкой сообщение об количестве записей. И все.
В последствии, я этот же таймер хотел использовать для временной остановки перебора значений в базе.
Наверх
 
 
IP записан
 
Rasen
Бета-тестер
Вне Форума



Сообщений: 143
Re: Таймер и функция delete
Ответ #8 - 21.09.2021 :: 10:19:57
 
Если функцию таймера Tick  вынести в отдельную функцию и обращение к ней разместить в методе формы CreateTimer, тогда функция timer:delete() удаляет таймер вполне корректно.
Код:
function Форма_Open( form, event )
timer = Me:CreateTimer(timerTick,Timer.stop) -- Timer.stop ( по умолчанию, можно без нее )
	return true  --открываем форму
end

function btLoadRefs_Click( control, event )
records = baseInfo:StringRequest("ОТ ДС01")  -- строчный запрос
recsCount = baseInfo.RecordsCount 
Me.Text = "...Идет загрузка данных" 
Me:Redraw();
AddToList(Me.listRecords,records)
Me.Text = "данные загружены"
timer:Start(1000)
end

function timerTick(tmr)      
	Beep();
	Me.Text = "Число записей -" .. recsCount;
	tmr:Stop()
end;


 

Наверх
 
 
IP записан
 
Zuluss
Бета-тестер
Вне Форума


Старинный пользователь
Кронос

Сообщений: 2 968
Санкт-Петербург
Re: Таймер и функция delete
Ответ #9 - 21.09.2021 :: 10:46:59
 
Сначала отвечу на последнее сообщение. Попозже на предыдущее.

Код:
Me:CreateTimer(timerTick,Timer.stop) 


Неправильная строчка. Должно быть  Код:
Me:CreateTimer(timerTick,1000,Timer.stop) 


Timer.stop имеет числовое значение 0, т.е. нулевой интервал срабатывания. Не проверял, но может быть или непрерывная работа, или отсутствие таковой вообще.
Наверх
 
 
IP записан
 
Zuluss
Бета-тестер
Вне Форума


Старинный пользователь
Кронос

Сообщений: 2 968
Санкт-Петербург
Re: Таймер и функция delete
Ответ #10 - 21.09.2021 :: 10:50:20
 
Не знаю что за поле у Вас rec:GetValue(3), но если оно текстовое и может быть большим (более нескольких сотен знаков), то его лучше ограничивать rec:GetValue(3):sub(1,50)
Наверх
 
 
IP записан
 
Zuluss
Бета-тестер
Вне Форума


Старинный пользователь
Кронос

Сообщений: 2 968
Санкт-Петербург
Re: Таймер и функция delete
Ответ #11 - 21.09.2021 :: 11:10:34
 
Мои тестовые испытания не выявили каких-либо глюков.
В коде исправьте функцию:

Код:
function Форма_CloseForm( form, event )
--timer:delete()
Me.self:CloseForm();  -- закрытие формы
-- У Вас обрабатывается событие при закрытии формы, а Вы в нем пытаетесь перед этим опередить и закрыть форму.
end 



Код:
function Форма_CloseForm( form, event )
if timer then timer:Stop();timer:delete() end
end 

Наверх
 
 
IP записан
 
Zuluss
Бета-тестер
Вне Форума


Старинный пользователь
Кронос

Сообщений: 2 968
Санкт-Петербург
Re: Таймер и функция delete
Ответ #12 - 21.09.2021 :: 16:31:03
 
Еще одно исправление:
Код:
function Форма_KeyPreview( event )
	if (event.Key == Keys.Escape) and (event.Type == FormKeyEvent.Pressed)
		then Форма_CloseForm()
	end
end 


на
Код:
function Форма_KeyPreview( event )
	if (event.Key == Keys.Escape) and (event.Type == FormKeyEvent.Pressed)
		then Me:CloseForm()
	end
end 

Наверх
 
 
IP записан
 
Rasen
Бета-тестер
Вне Форума



Сообщений: 143
Re: Таймер и функция delete
Ответ #13 - 22.09.2021 :: 07:51:47
 
Спасибо
Наверх
 
 
IP записан
 
Переключение на Главную Страницу Страниц: 1
Послать Тему Печать