Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / try/finally в циклах. / 16 сообщений из 16, страница 1 из 1
12.10.2017, 19:01:48
    #39535621
Алексей Кл
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Появился вот такой код:
Код: 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
12.10.2017, 19:15:00
    #39535625
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Как-то так
Код: 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
12.10.2017, 19:26:35
    #39535633
Кар-Кар
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Код: 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
12.10.2017, 19:29:26
    #39535636
Кар-Кар
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
А, точно
Код: 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
12.10.2017, 19:39:57
    #39535639
Кар-Кар
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
С except вообще забавная история.
Пытается прога что-нибудь сделать допустим
Код: pascal
1.
2.
3.
4.
5.
6.
7.
try
  Do1;
  Do2;
  Do3;
except

end;


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

Спасибо. Так разве что:
Код: 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
12.10.2017, 20:09:02
    #39535650
defecator
Модератор форума
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Кар-КарС 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
12.10.2017, 20:09:32
    #39535651
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
[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
12.10.2017, 20:18:58
    #39535662
Алексей Кл
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Соколинский БорисЭто еще зачем?
В моем варианте, если ошибка в BeforeRefresh флаг останется false.

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

Хорошо работает - и ладно. Немного, правда, некрасиво. С другой стороны, если работать будет плохо - то никакая красота не поможет.
...
Рейтинг: 0 / 0
12.10.2017, 20:58:14
    #39535680
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Соколинский БорисКак-то так
Код: 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
12.10.2017, 21:03:33
    #39535683
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Алексей КлМеня смущают многоэтажные try finally except.На быстродействие это, скорее всего, никак не влияет. В плане громоздкости кода.. Ну можно методом имени softwarer-а запилить какие-нибудь вспомогательные - объекты с интерфейсом, которые в деструкторе будут вызывать AfterRefresh. Но если там будет исключение - туши свет.
...
Рейтинг: 0 / 0
12.10.2017, 22:24:04
    #39535710
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Все просто. Заменить цикл рекурсией
Код: 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
12.10.2017, 22:27:11
    #39535714
_Vasilisk_
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Или даже так
Код: 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
12.10.2017, 22:54:35
    #39535722
Соколинский Борис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Соколинский БорисНо если там будет исключение - туши свет. Впрочем, нет.
Код: 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
13.10.2017, 10:36:53
    #39535857
schi
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
try/finally в циклах.
Соколинский Борис,

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

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


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