Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.11;
Скачать: [xml.tar.bz2];




Вниз

Подвисание формы при выполнении цикла 


Vladimir K.   (2002-02-22 04:42) [0]

Как избежать подвисания формы при выполненнии цикла?? Плз, помогите разобраться..
ЗЫ: application.processmessages; - помогает только частично



nick_vstu   (2002-02-22 05:42) [1]

Может у Вас в цикле есть какие-нибудь сложные операции, исполнение которых приводит к "подвисанию".



Артемий   (2002-02-22 07:03) [2]

Цикл плиз.



ilysha   (2002-02-22 08:44) [3]

Поставь application.processmessages; в нескольких местах.
Хотя, если у тебя выполняется sql-запрос, то это не поможет.



Виктор Щербаков   (2002-02-22 09:16) [4]


> application.processmessages; - помогает только частично

Подробнее!



VictorT   (2002-02-22 11:00) [5]

Я так понял, что ты имеешь в виду, что пока не закончится некий достаточно длинный процесс, форма не реагирует на события (нажатие кнопок и т.п.). Это решается помещением этого процесса в отдельный поток (tread).



Sergii   (2002-02-24 22:46) [6]

Если по смыслу задачи можно обойтись без отдельного потока - то и не надо его создавать. ProcessMessages прекрасно работает. А вот куда его вставлять - это цикл смотреть надо.



panov   (2002-02-24 23:17) [7]

Не всегда оптимально использовать Application.ProcessMessages.
Все же время при переключении на процедуру обработки сообщений и сама обработка откусывают от времени работы цикла значительный кусок.

Как раз создание отдельного потока для вычислений решает все проблемы - и интерфейс в основном потоке не блокируется, и вычислительный цикл в отдельном потоке не тормозится...



Aleks1   (2002-02-25 01:34) [8]

Имхо, ProcessMessages нужен только, если нужно визуальное обновление чего-либо и не важно где, в основном потоке или дополнительном.



Sergii   (2002-02-25 02:56) [9]




> Не всегда оптимально использовать Application.ProcessMessages.
> Все же время при переключении на процедуру обработки сообщений
> и сама обработка откусывают от времени работы цикла значительный
> кусок.
>


Конечно не всегда. Насчет значительности времени - не знаю, спорить не буду, это надо профайлером смотреть. Однако, процедуры обработки сообщений никуда не денуться - основной поток их будет так же отрабатывать. И еще добавиться код синхронизации.

> Как раз создание отдельного потока для вычислений решает
> все проблемы - и интерфейс в основном потоке не блокируется,
> и вычислительный цикл в отдельном потоке не тормозится...

Все это хорошо, если мы имеем 2 и более процессорную машину. Загоняем вычисления на отдельный процессор и получаем удовольствие. Если брать реальные десктопы, то, например, в данный момент у меня крутиться около 353 потока - выгода будет уже не та. И Vladimir K о своей задаче ничего не говорил. Т.е. я так понимаю, работа цикла все-же не очень продолжительная - например, 15 секунд, в течение которго крутиться прогресс бар. Ну и зачем городить огород из потоков в таком случае? ИМХО это может быть не оправданно - чем сложнее система, тем она менее устойчива :)



Aleks1   (2002-02-25 03:57) [10]

> Sergii © (25.02.02 02:56)
Со многим согласен, кроме

>Все это хорошо, если мы имеем 2 и более процессорную машину. >Загоняем вычисления на отдельный процессор и получаем >удовольствие.

В случае однопроцессорной системы, при использовании отдельного потока для вычислений, мы имеем более "дружественный" интерфейс для пользователя!



panov   (2002-02-25 11:20) [11]

Sergii © (25.02.02 02:56)
Однако, процедуры обработки сообщений никуда не денуться - основной поток их будет так же отрабатывать.
Совершенно верно, но в данногм случае мы к обработке всех сообщений добывляем еще и принудительное выполнение этой процедуры в цикле, что не может быть хорошо.

Если брать реальные десктопы, то, например, в данный момент у меня крутиться около 353 потока - выгода будет уже не та.

Тоже верно. Но ведь выгода все равно будет?



Sergii   (2002-02-25 13:07) [12]

Да, безусловно все так. Но относительно абстрактной задачи решение подсказать неполучиться. Приведу код для качественной оценки времени выполнения:


type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TProcessThread = class(TThread)
private
InitTime: DWord;
procedure ShowResults;
protected
procedure Execute; override;
end;


var
Form1: TForm1;
MyThread: TProcessThread;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
InitTime: DWord;
ProcessTime: DWord;
A, B, C: double;
begin
InitTime := GetTickCount;
//Randomize;
I := 0;
while I < 500000 do
begin
{ A := Random;
B := Random;
C := SQRT(A*B); }
Application.ProcessMessages;
Inc(I);
end;
ShowMessage(IntToStr(GetTickCount - InitTime) + " ms");
end;

{ ProcessThread }

procedure TProcessThread.Execute;
var
I: Integer;
ProcessTime: DWord;
A, B, C: double;
begin
InitTime := GetTickCount;
//Randomize;
I := 0;
while I < 500000 do
begin
{A := Random;
B := Random;
C := SQRT(A*B); }
Inc(I);
end;
Synchronize(ShowResults);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
MyThread := TProcessThread.Create(False);
end;

procedure TProcessThread.ShowResults;
begin
ShowMessage(IntToStr(GetTickCount - InitTime) + " ms");
end;
CODE>

Оптимизация выключена. В моем случае получилось для пустых цыклов выигрыш по скорости в 13 раз со стороны потока. Если раcкоментировать участки, где делается что-то "полезное", то выигрыш уже был где-то в 1,7 - 1,9 раз. Собственно об этом и речь - чем меньше итераций и чем больше время одной итерации - тем более оправдано применение ProcessMessages.

P.S. А насчет двухпроцессорной машины - это я к тому, что я считаю, что не всегда то, что работает быстрее, является более оптимальным.





Sergii   (2002-02-25 13:09) [13]


Прошу прощения за незакрытый тег.



kingdom   (2002-02-25 13:22) [14]

К минусам ProcessMessages...
Если использовать ProcessMesssages, и во время работы цикла нажать, например какое-нить меню в этом же приложении,
то цикл остановиться пока пользователь не выйдет из меню...



Sasha9   (2002-02-25 13:26) [15]

да и кнопка закрыть(Alt+F4) не действует



panov   (2002-02-25 15:50) [16]

Хочу еще в заключение сказать, что для задач, для которых скорость выполнения цикла не критична, то тут я целиком согласен с Sergii © - самое лучшее использовать ProcessMessages. А вот если необходима оптимизация, то тут уже придется думать как раз о дополнительном потоке, о методах синхронизации.

Кстати, автору вопроса, по-видимому, все это не интересно. Поэтому обсуждение, в принципе, можно закончить. Хотя, если есть желание обсудить подробнее, то можно создать отдельную ветку, и, я думаю, что мастера и знатоки Windows присоединятся к обсуждению...




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.03.11;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.76 MB
Время: 0.019 c
1-32482           GovoRun               2002-02-23 13:49  2002.03.11  
InitialDir for OpenDialog


3-32387           Draculenok            2002-02-12 09:35  2002.03.11  
Как мне заполнить Combobox из поля базы данных!!!!!!!!!!!!!!!!!


7-32597           alex16                2001-11-30 06:53  2002.03.11  
CD


1-32495           Zool                  2002-02-24 17:51  2002.03.11  
Zip


1-32461           Lotus                 2002-02-23 13:22  2002.03.11  
цветной фрагмент RichEdit