Форум: "Основная";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
ВнизКак установить лимит по времени на некую процедуру ? Найти похожие ветки
← →
Wolf © (2008-01-08 21:29) [0]Приветствую.
вопрос в следующем.
У нас есть цикл :
for i:=0 to 100000 do
begin
n:=getData(i);
end;
Внутри цикла вызывается функция getData
Вопрос: Как наложить ограничение по времени на выполнение функции getData ? например 15 сек
и если за 15 сек функция не вернула результат продолжить выполнение программы. т.е цикл пойдет дальше и вызовет ту же функцию getData но уже с другим значением.
Зачем это нужно: В цикле обрабатываются очень много значений. И заказчик хочет указать в настройках лимит времени для выполнение функции getData
Как такое реализовать ?
← →
Правильный_Вася (2008-01-08 21:41) [1]1. таймер + флаг
2. таймер + отдельный поток
3. в самой процедуре проверку поставить, чтоб абортилась при оверхеде
← →
guav © (2008-01-08 21:43) [2]Прийдётся проверять не прошло ли указанное время внутри самой функции, и если прошло - выходить.
Использовать TerminateThread или "забывать" про выполняющуюся нить не следует.
Время проверять можно через GetTickCount. Более гибким может быть использование объектов синхронизации (Event, Waitable timer) и отдельного потока.
Выодить можно используя исключения или просто завершая работу функци.
← →
Wolf © (2008-01-09 18:37) [3]Фишка в том что вызывается процедура из сишной библиотеки к которой я не имею доступа :( и что то вставить в неё не получиться :(
Нашел такой код:
var
TimeEnd: TEvent;
begin
if TimeEnd.WaitFor(15000)=wrSignaled then
// Вызов функции
else
// Если время вышло вроде
но немогу в нем разобраться ... выдает ошибку ... скажите это то что нужно или левый вообще код ?
← →
TStas © (2008-01-09 20:54) [4]Я делал намного проще.
var EndTime: TDateTime;
EndTime := Date + Time + TimeLimit; //TimeLimit - собственно ограничение
repeat
YourProcedure; //У меня там файл писался на диск, но не важно
If Date + Time > EndTime then break; //Все, время вышло, нафиг рву цикл
Application.ProgressMessages; //Это чтобы зависшей программа не выглядела.
until .... //У меня было FileExists
← →
Правильный_Вася (2008-01-09 21:37) [5]
> Я делал намного проще.
это не работает, т.к.YourProcedure;
выполнится до конца или за минуту, или за сутки
и ничего ты не оборвешь, пока ни выполнится
← →
guav © (2008-01-09 22:57) [6]> [3] Wolf © (09.01.08 18:37)
В таком варианте нормального решения нет.
Какой интерфейс экспортируется библиотекой, и что эта библиотека делает ?
Может, есть способ прервать функцию (например, заставив ещё кинуть SEH исключение, или закрыв используемы ей дескритор).
← →
@!!ex © (2008-01-09 23:03) [7]> [6] guav © (09.01.08 22:57)
А грохнуть поток в котором она выполняется чем не вариант?
← →
maxistent © (2008-01-10 00:29) [8]вот, осмелюсь предложить свой вариант. может что-то и не совсем красиво, но работает замичатильна :о)
type
TParam=record
i:integer;
n:integer;
done:boolean;
end;
PParam=^TParam;
function GetData(index:integer):integer; {для проверки}
begin
sleep((Random(4)+1)*1000);
result:=index mod 3;
end;
Procedure MyThread(param:PParam);
begin
param.n:=GetData(param.i);
param.done:=true;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i:integer;
n:integer;
h:THandle;
id:DWord;
p:PParam;
t1,t2,t3,t4:word;
StartTime,TheTime:dword;
TimeLimit:integer;
begin
randomize;
TimeLimit:=3;//3 секунды
for i:=1 to 10 do
begin
new(p);
p^.i:=i;
p^.done:=false;//обозначаем как "нифига, не готово ещё"
h:=BeginThread(nil,0,@MyThread,p,0,id);//создаём отдельный поток
DecodeTime(Time,t1,t2,t3,t4);
StartTime:=t1*3600+T2*60+T3;
//засекаем время и...
repeat
DecodeTime(Time,t1,t2,t3,t4);
TheTime:=t1*3600+T2*60+T3;
{здесь можно выдавать что-то вроде "ЖДИТЕ..."}
application.ProcessMessages;
until (p^.done) or (TheTime>=StartTime+TimeLimit);
if p^.done then
n:=p^.n //ура, процедура уложилась во время!
else
n:=-1;//вот цкотино!
TerminateThread(id,0);//"сносим" поток
CloseHandle(h);
Dispose(p);
memo1.Lines.Add("index="+IntToStr(i)+", result="+IntToStr(n));
application.ProcessMessages;
end;
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2008.10.12;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.043 c