Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.10.12;
Скачать: CL | DM;

Вниз

Как установить лимит по времени на некую процедуру ?   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.017 c
2-1220874482
aaandy21
2008-09-08 15:48
2008.10.12
как связать написанную на Delphi DLL c VC?


2-1219171581
+++vist+++
2008-08-19 22:46
2008.10.12
Динамический массив записей


2-1220801949
Начинающий1
2008-09-07 19:39
2008.10.12
Логарифм


15-1219671790
Vlad Oshin
2008-08-25 17:43
2008.10.12
можно ли поставить oracle 10gXE(бесплатный который) копированием?


6-1193900716
Sergl
2007-11-01 10:05
2008.10.12
Не пойму где ошибка(сокеты)...