powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / try/finally в циклах.
16 сообщений из 16, страница 1 из 1
try/finally в циклах.
    #39535621
Алексей Кл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Появился вот такой код:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
  for i := 0 to Count - 1 do
    Items[i].BeforeRefresh;
  try
    BroadcastRefresh;
  finally
    for i := 0 to Count - 1 do
      Items[i].AfterRefresh;
  end;


Скопом для каждого итема списка надо выполнить BeforeRefresh, а в конце так-же для каждого AfterRefresh.
Эксепшен может быть везде (BeforeRefresh, BroadcastRefresh, AfterRefresh). Там я рисую графику. BroadcastRefresh должен быть вызван в любом случае.
Как гарантировать, чтоб на каждый Items[i].BeforeRefresh был свой Items[i].AfterRefresh?

Если бы не было циклов, я бы написал:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
  try
    Error := BeforeRefresh;
  finally
    try
      Refresh;
    finally
      if not Error then
        AfterRefresh;
    end
  end;


Тоже жуть.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535625
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как-то так
Код: 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.
25.
var ItemFlags: array of boolean;
...
begin
  SetLength(ItemFlags, Count);
  for i:=0 to count-1 do  ItemFlags[i]:=0;
  try
    try
      for i:=0 to count-1 do begin
        Items[i].BeforeRefresh;
        ItemFlags[i]:=true;
      end;
    finally
       BroadcastRefrech;
    end;
  finally
    for i:=0 to count-1 do
    if ItemFlags[i] then
    try
      Items[i].AfterRefresh;     
    except
      //Здесь нужно обработать исключение
    end;
  end;    
end;
А вообще нужно над архитектурой подумать.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535633
Кар-Кар
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
  for i := 0 to Count - 1 do
  begin
    try
      Items[i].BeforeRefresh;
    except
  
    end;
    try
      Items[i].AfterRefresh;
    except

    end;
  end;
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535636
Кар-Кар
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, точно
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
  for i := 0 to Count - 1 do
  begin
    try
      Items[i].BeforeRefresh;
    except
  
    end;
    try
      Items[i].BroadcastRefresh;
    except

    end;
    try
      Items[i].AfterRefresh;
    except

    end;
  end;
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535639
Кар-Кар
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
С except вообще забавная история.
Пытается прога что-нибудь сделать допустим
Код: pascal
1.
2.
3.
4.
5.
6.
7.
try
  Do1;
  Do2;
  Do3;
except

end;


Вываливается exception на Do2. Хоть кто-нибудь задумывался о том, что необходимо в этом случае отменять Do1? Чтобы вернуть данные (если какие-то там изменились) в исходное состояние. Такие баги со временем в проге можно увидеть, когда операция лишь частично выполняется.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535644
Алексей Кл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Соколинский Борис,

Спасибо. Так разве что:
Код: 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.
25.
26.
27.
SetLength(ItemFlags, Count);
  for i := 0 to Count - 1 do
    ItemFlags[i] := False;
  try
    try
      for i := 0 to Count - 1 do
        begin
          ItemFlags[i] := True;
          try
            Items[i].BeforeRefresh;
          except
            ItemFlags[i] := False;
            // Здесь нужно обработать исключение
          end;
        end;
    finally
      BroadcastRefrech;
    end;
  finally
    for i := 0 to Count - 1 do
      if ItemFlags[i] then
        try
          Items[i].AfterRefresh;
        except
          // Здесь нужно обработать исключение
        end;
  end;


Соколинский БорисА вообще нужно над архитектурой подумать.

Не получается. Опасность BeforeRefresh и AfterRefresh преувеличил. Там вешается картинка, потом снимается. Но если ошибка, то останется висеть.

Кар-Кар,
В один цикл не получится. Там BroadcastRefrech специфический.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535650
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Кар-КарС except вообще забавная история.
Пытается прога что-нибудь сделать допустим
Код: pascal
1.
2.
3.
4.
5.
6.
7.
try
  Do1;
  Do2;
  Do3;
except

end;



Вываливается exception на Do2. Хоть кто-нибудь задумывался о том, что необходимо в этом случае отменять Do1? Чтобы вернуть данные (если какие-то там изменились) в исходное состояние. Такие баги со временем в проге можно увидеть, когда операция лишь частично выполняется.

запили лесенку ))))))

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
try
  Do1;
  try
     Do2;
     try
         Do3;
     except
        raise;
     end;
  except
     raise;
  end;
except
end;
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535651
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quote Алексей Кл]Соколинский Борис,
Спасибо. Так разве что:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SetLength(ItemFlags, Count);
      for i := 0 to Count - 1 do
        begin
          ItemFlags[i] := True;
          try
            Items[i].BeforeRefresh;
          except
            ItemFlags[i] := False;
            // Здесь нужно обработать исключение
          end;


Это еще зачем?
В моем варианте, если ошибка в BeforeRefresh флаг останется false.


Соколинский Борис Не получается. А кто мешает инкапсулировать флаг в объект и выставлять/снимать в самих методах Before../After?
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535662
Алексей Кл
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Соколинский БорисЭто еще зачем?
В моем варианте, если ошибка в BeforeRefresh флаг останется false.

Цикл прервется.
Соколинский Борис А кто мешает инкапсулировать флаг в объект и выставлять/снимать в самих методах Before../After?
Это частности.
Меня смущают многоэтажные try finally except.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535676
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей Кл,

Хорошо работает - и ладно. Немного, правда, некрасиво. С другой стороны, если работать будет плохо - то никакая красота не поможет.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535680
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский БорисКак-то так
Код: 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.
25.
var ItemFlags: array of boolean;
...
begin
  SetLength(ItemFlags, Count);
  for i:=0 to count-1 do  ItemFlags[i]:=0;
  try
    try
      for i:=0 to count-1 do begin
        Items[i].BeforeRefresh;
        ItemFlags[i]:=true;
      end;
    finally
       BroadcastRefrech;
    end;
  finally
    for i:=0 to count-1 do
    if ItemFlags[i] then
    try
      Items[i].AfterRefresh;     
    except
      //Здесь нужно обработать исключение
    end;
  end;    
end;
А вообще нужно над архитектурой подумать.



Только в последнем цикле нет смысла продолжать, если ItemFlags[i] равен false, так как исключение в верхнем цикле прервет его.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535683
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КлМеня смущают многоэтажные try finally except.На быстродействие это, скорее всего, никак не влияет. В плане громоздкости кода.. Ну можно методом имени softwarer-а запилить какие-нибудь вспомогательные - объекты с интерфейсом, которые в деструкторе будут вызывать AfterRefresh. Но если там будет исключение - туши свет.
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535710
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все просто. Заменить цикл рекурсией
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
procedure DoProcess(AIdx: Integer);
begin
  Items[AIdx].BeforeRefresh;
  try
    if AIdx < Count - 1 do
      DoProcess(AIdx + 1)
    else
      BroadcastRefresh;
  finally
    Items[AIdx].AfterRefresh;
end;

if Count > 0 then
  DoProcess(0)
else
  BroadcastRefresh;
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535714
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Или даже так
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
procedure DoProcess(AIdx: Integer);
begin
  if AIdx < Count do begin
    Items[AIdx].BeforeRefresh;
    try
      DoProcess(AIdx + 1)
    finally
      Items[AIdx].AfterRefresh;
  end else
      BroadcastRefresh;
end;

DoProcess(0)
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535722
Соколинский Борис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский БорисНо если там будет исключение - туши свет. Впрочем, нет.
Код: 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.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
type
  THolder=class(TInterfacedObject)
  private
    FObj: TItemClass;
  public
    constructor create(AObj: TItemClass);
    destructor destroy; override;
  end;

constructor THolder.create(AObj: TItemClass);
begin
  FObj:=AObj;
end;

destructor THolder.destroy;
begin
  try
    FObj.AfterRefresh;
  except
  end;

  inherited;
end;


procedure DefineHolder(AObj: TItemClass; out Holder: IUnknown);
begin
  try
    AObj.BeforeRefresh;
    Holder:=THolder.create(AObj);
  except
  end;
end;


//вызывалка
var Holders: array of IUnknown;
...
begin
  SetLength(Holders, Count);
  for i:=0 to count-1 do DefineHolder(Items[i], Holders[i]);
  BroadcastRefresh;
end;
...
Рейтинг: 0 / 0
try/finally в циклах.
    #39535857
schi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Соколинский Борис,

"Зачем делать сложно то, что проще простого ?"

в 20865451 нормальный код был, а главное - понятный.
...
Рейтинг: 0 / 0
16 сообщений из 16, страница 1 из 1
Форумы / Delphi [игнор отключен] [закрыт для гостей] / try/finally в циклах.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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