Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
1-1199816989
Wolf
2008-01-08 21:29
2008.10.12
Как установить лимит по времени на некую процедуру ?


2-1220073543
DarkLord
2008-08-30 09:19
2008.10.12
Имитация DblClick


2-1220607350
igor666
2008-09-05 13:35
2008.10.12
Помогите с курсорами.


15-1219088046
Тимохов
2008-08-18 23:34
2008.10.12
Helpdesk и работа с пользователями


2-1220614191
KirillRepin
2008-09-05 15:29
2008.10.12
Буфер обмена





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский