powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как прекратить выполнение события из продцедуры?
25 сообщений из 32, страница 1 из 2
Как прекратить выполнение события из продцедуры?
    #39859320
InterSky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Произошло какое-то событие, ну допустим OnButton.Click, и оно выполняется...
Если в теле этого события встретится Exit, то выполнение прекращается.
Но если, в нём вызывается процедура, и уже в ней встретится Exit, то прекратится исполнение только этой процедуры. А можно ли из процедуры остановить выполнение всего события?

Конечно можно делать костыли: можно превратить процедуру в функцию, и в ней перед выходом подавать значение: выполнилась нормально или прекратила работу через Exit, а потом на основания полученного от функции значения делать такой же выход и в блоке вызвавшем функцию. Но это костыли! Возможно тут кто-то возмущённо скажет, что НЕТ, что Именно так и должна работать программа, последовательно и продуманно выполняя каждое действие... Но по такой логике и Exit не должен существовать, а тем более ужасный Halt.

Ну или как аналог взять циклы: там есть Continue (так же как Exit прерывающий выполнение блока), но есть и Break - который прекращает выполнение всего цикла (вот аналог такого для прекращения события я и ищу).

P.S. Предвижу что кто-то вместо решения задачи, будет говорить о лени, о том что дескать поставить одну проверку, или даже вписать вместо простого вызова процедуры, конструкцию типа: if MyFunction=666 then Exit - это даже красиво... Но эти процедура приводящая к остановке может иметь и десятую степень вложенности, и тогда переделывать процедуры в функции надо будет в десятках мест. Да и где-то может оказаться что остановка произойдёт в функции, а она уже и так что-то возвращает...
Тут сразу же появятся люди которые предложат проверять не возвращаемое событие, а специально созданную глобальную переменную. И по всему коду, на всех уровнях вложенности, после выхода из каждой процедуры или функции связанной с этим событием надо будет выставлять проверки выхода (если внутри могла быть изменена эта глобальная переменная).

Тут уже кто-то ужаснётся - Что так у тебя за монстр, многоуровневый и остановить которого может потребоваться не в одном каком-то месте, а во многих местах на разных уровнях?
Всё просто: Одна кнопка, и она вызывает событие который производит анализ большого массива данных. Расчёты производятся десятками разных методов. У каждого разный метод. Где-то идём рекурсивно, где-то проверяем на возможность ошибок перебором углубляясь вглубь и сравнивая с другими блоками массива, где-то пытаемся вычислить что может произойти и просчитываем дальнейшие решения на базе имеющихся данных, чтобы предугадать события, где-то просто оптимизируем меняя одну последовательно данных на другую... И на разных уровнях вложенности есть возможность отображения на экране (изменение данных, изменение данных, отметка области с ошибками, удаление того что не повлияет ни на что... Всем выводом занимается одна процедура (вызываемая из сотни мест на разных уровнях вложенности процедур и функций). И чтобы сделать пошаговый вывод, достаточно было бы в конце этой функции вызвать какой-то условный GlobalExit (или EventExit), который бы остановил всё действие единственного события. Чтобы оператор проанализировал изменения, и принял решение о продолжении анализа уже с другими параметрами или с другим приоритетом или в другом направлении. Не хочется в случае пошагового режима после каждого вывода данных делать бесконечный цикл (таким образом останавливая работу программы) и Halt'ить её для того чтобы оператор продолжил анализ с другими параметрами.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859327
Aniskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
type
  EEverythingIsOk = class(Exception);

procedure Job;
begin
  // Some code
  if SomeCondition then 
    raise EEverythingIsOk.Create(''); // вместо Exit
  // Some code
end;

procedure TForm6.btn1Click(Sender: TObject);
begin
  try
    Job;
  except
    on E: EEverythingIsOk do
    else raise;
  end;
end;
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859331
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Aniskinraise EEverythingIsOk

Обычно используется Abort;
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859365
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InterSkyА можно ли из процедуры остановить выполнение всего события?
Можно процедуру объявить функцией и анализировать её результат.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859387
InterSky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wadmanInterSkyА можно ли из процедуры остановить выполнение всего события?
Можно процедуру объявить функцией и анализировать её результат.
Процедура которую вы предложили объявить функцией и анализировать её результат, сама может быть вызвана из другой функции вызванной из процедуры сработавшей по OnClick. Этот вариант предусмотрительно разобран в вопросе, чтобы заранее избавиться от ответов типа вашего...

Aniskin - спасибо!
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859394
goldmi45
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InterSky, обработка исключительных ситуаций может вам помочь.
InterSky...
Ну или как аналог взять циклы: там есть Continue (так же как Exit прерывающий выполнение блока), но есть и Break - который прекращает выполнение всего цикла (вот аналог такого для прекращения события я и ищу).


Break прерывает цикл, но не прерывает процедуру. Exit - прерывает не только цикл, но и процедуру.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859399
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovОбычно используется Abort;
+1
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859455
InterSky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
goldmi45InterSky, обработка исключительных ситуаций может вам помочь.
InterSky...
Ну или как аналог взять циклы: там есть Continue (так же как Exit прерывающий выполнение блока), но есть и Break - который прекращает выполнение всего цикла (вот аналог такого для прекращения события я и ищу).


Break прерывает цикл, но не прерывает процедуру. Exit - прерывает не только цикл, но и процедуру.
Вы знаете что такое аналогия?
Представьте язык программирования, в котором нету циклов (а так же goto и рекурсии). Если вам надо было бы что-то выполнить в цикле от 1 до 5, вы бы писали:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
procedure outerProc;

 Procedure innerProc(const n : Integer);
 begin
 // Тут пишется то что вы писали бы в теле цикла.
 end;

begin
innerProc(1);
innerProc(2);
innerProc(3);
innerProc(4);
innerProc(5);
end;



То есть, цикл - это процедура внутри процедуры.
Если вместо комментария вы впишите текст программы и там встретится Exit, он сработает как Continue в циклах и завершит лишь внутреннюю процедуру "innerProc". По аналогии, встречающийся в цикле Break завершил бы внешнюю процедуру "outerProc".
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859464
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InterSky,

"Выдыхай, бобер" - ©.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859493
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InterSky,

авторНо если, в нём вызывается процедура, и уже в ней встретится Exit, то прекратится исполнение только этой процедуры. А можно ли из процедуры остановить выполнение всего события?

надежнее и проще всего решается исключениями
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859496
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть еще более красивый вариант:


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
function MyProc: boolean;
begin
//
  if something then Exit(False);
//
end;


procedure Main;
begin
  If not MyProc then Exit;
end;
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859502
InterSky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatЕсть еще более красивый вариант:

If not MyProc then Exit;

Я же объяснил что и из функций тоже надо выходить...
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859503
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InterSky,

Меняйте функцию.

funtion myFunc: integer;
на
funtion myFunc(out Res: integer): boolean;
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859504
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Собственно половина winAPI так работает.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859508
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
InterSkyЯ же объяснил что и из функций тоже надо выходить...

Слово "аборт" ты при чтении топика пропустил как "шибка нипанятное"?
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859511
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Abort - медленно.
Если таких выходов предпологается много - это очень плохое решение.

Как-то у меня коллега сделал как-то так:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
function IsFloat(Text: string): boolean
begin
   try
      StrToFloat(Text);
      Result:=True;
   except
      Result:=False;
   end;
end;


А потом удивлялся, что это у него все тормозит нещадно на больших объемах данных.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859516
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreatА потом удивлялся, что это у него все тормозит нещадно на больших объемах данных.

Тормозило у него в основном из-за передачи строки по значению скорее всего. SEH,
используемый для исключений, считается быстрейшим способом их обработки из всех.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859525
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
function IsFloat(const Text: string): boolean;
begin
   try
      StrToFloat(Text);
      Result:=True;
   except
      Result:=False;
   end;
end;

var
  i : integer;
  c : cardinal;
begin
  c:=getTickCount;
  for i:=0 to 1000 do begin
    IsFloat('2354fvbcv');
  end;
  writeln(getTickCount-c);
  c:=getTickCount;
  for i:=0 to 1000 do begin
    StrToFloatDef('2354fvbcv',0);
  end;
  writeln(getTickCount-c);



11297
0
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859535
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat11297
0

Ну, у меня разница не так велика, но таки да, второй цикл в 100 раз быстрее первого.
Очевидно, туда вмешиваются накладные расходы менеджера памяти. Жаль в Дельфи нельзя
выкинуть статический объект исключения.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859544
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

0.1 секунды на мнеджер памяти не списать.

Если бы дело было только в нем то было бы не 100 вызовов в секунду а как минимум 10000.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859545
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Упс, 0.01 сек. Опечатался.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859546
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat0.1 секунды на мнеджер памяти не списать.

Это у тебя что-то с таймером. Мне пришлось добавить два нуля в цикл чтобы получить
4087
47
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859547
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выброс исключения тормозит, да. Там, где предполагается частый отрицательный результат, лучше юзать возврат флага/кода ошибки
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859549
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovЭто у тебя что-то с таймером.
Не, реально 11 секунд.

Delphi 10.2, Release, Core i5-6500 3.2 GHz.
...
Рейтинг: 0 / 0
Как прекратить выполнение события из продцедуры?
    #39859551
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Под x64 быстрей.

x86 - 11391
х64 - 4265
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Как прекратить выполнение события из продцедуры?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]