Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> D2010: Регулярное обновление строки состояния 
:(
    Опции темы
grh
Дата 29.2.2016, 15:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.11.2010

Репутация: нет
Всего: нет



Всем привет. Иногда при выполнении долговременных процедур Delphi-приложение "подвисает", и в том числе "подвисает" строка состояния. Что нужно сделать для того, чтобы строка состояния регулярно обновлялась?
PM MAIL   Вверх
Doga
Дата 29.2.2016, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 20.12.2007
Где: Россия, Обнинск

Репутация: нет
Всего: нет



Привет.

Application.ProcessMessages;

Хотя, если "подвисает" надолго, можно подумать об организации параллельного потока.  

PM MAIL WWW   Вверх
dnek
Дата 1.3.2016, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 1.4.2013

Репутация: нет
Всего: нет



Application.ProcessMessages не так хороша как Вам кажется и далеко не всегда подходит для прорисовки контролов, а в большинстве случаев её вообще не следует использовать.
Так что для выполнения "долгоиграющих" процедур наилучший (если не единственный) выход - отдельный поток.

Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
Doga
Дата 1.3.2016, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 20.12.2007
Где: Россия, Обнинск

Репутация: нет
Всего: нет



2dnek:
Application.ProcessMessages не так плоха как Вам кажется  smile  

Иногда она хороша, иногда не очень...

Я предложил два варианта. В любом случае, выбор за разработчиком.
PM MAIL WWW   Вверх
dnek
Дата 2.3.2016, 08:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 0
Регистрация: 1.4.2013

Репутация: нет
Всего: нет



Если использовать Application.ProcessMessages в теле цикла, то сильно грузится проц. Лучше уж тогда ввести какой-нибудь флаг и использовать связку Application.HandleMessage + обработчик Application.OnIdle. А вообще использование Application.ProcessMessages в долгоиграющих процедурах - плохой код (и уже давно). Это было допустимо в Delphi 7, а после (я имею года а не версию) уже считалось некорректным. Старайтесь писать чистый код!


Этот ответ добавлен с нового Винграда - http://vingrad.com
PM MAIL   Вверх
ZBugz
Дата 3.3.2016, 07:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 631
Регистрация: 15.2.2006
Где: Москва

Репутация: 6
Всего: 6



Цитата(dnek @ 2.3.2016,  08:22)
Если использовать Application.ProcessMessages в теле цикла, то сильно грузится проц. Лучше уж тогда ввести какой-нибудь флаг и использовать связку Application.HandleMessage + обработчик Application.OnIdle. А вообще использование Application.ProcessMessages в долгоиграющих процедурах - плохой код (и уже давно). Это было допустимо в Delphi 7, а после (я имею года а не версию) уже считалось некорректным. Старайтесь писать чистый код!


Этот ответ добавлен с нового Винграда - http://vingrad.com

Пусть таймер поставит и каждую секунду обновляет через Application.ProcessMessages и проц не грузится, делов то
PM MAIL   Вверх
Doga
Дата 4.3.2016, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 20.12.2007
Где: Россия, Обнинск

Репутация: нет
Всего: нет



2dnek:
Цитата

Если использовать Application.ProcessMessages в теле цикла, то сильно грузится проц.

Откуда Вы это взяли? С целью проверки этого утверждения был создан простенький тест.

В тесте реализовано 3 режима. В каждом из них производится получение системного времени, 
преобразование его в строку и её вывод на экран: 

Код

Panel1.Caption := DateTimeToStr(Now);


1.В первом режиме производится просто получение времени 10 000 000 раз в цикле без возможности 
обновить время на экране и с эфектом заморозки приложения до окончания работы цикла. 
Этот режим включён в тест для наглядности.

2.Во втором режиме  время опрашиватся в цикле пока не будет нажата кнопка "Стоп". 
Для обновления используется ProcessMessages. Время на экране обновляеттся своевременно,  
эфекта заморозки приложения нет.


2.В третем режиме  время опрашиватся в цикле параллельного потока пока не будет нажата кнопка "Стоп". 
Для обновления показаний времени используется Synchronize. Время на экране обновляеттся своевременно,  
эфекта заморозки нет.

Код

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ExtCtrls;

type

  TTimeThread =  class(TThread)
  protected
    procedure Execute; override;
    procedure UpdateTime;

  end;


  TForm1 = class(TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    Button4: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button4Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    { Private declarations }
    CanContinue : boolean;
    TimeThread : TTimeThread;
    
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

//Заморозка
procedure TForm1.Button1Click(Sender: TObject);
var
  k : Integer;

begin
  Button1.Enabled := false;
  Button2.Enabled := false;
  Button3.Enabled := false;
  Button4.Enabled := false;

  TimeThread := nil;

  for k := 0 to 9999999 do
  begin
    //Конечно, Caption обновится только после выхода из цикла
    Panel1.Caption := DateTimeToStr(Now);
  end;

  Button1.Enabled := true;
  Button2.Enabled := true;
  Button3.Enabled := true;
  Button4.Enabled := true;
end;

//ProcessMessages
procedure TForm1.Button2Click(Sender: TObject);
begin
  Button1.Enabled := false;
  Button2.Enabled := false;
  Button3.Enabled := false;

  TimeThread := nil;

  CanContinue := true;

  while CanContinue do 
  begin
    Panel1.Caption := DateTimeToStr(Now);
    Application.ProcessMessages;
  end;

  Button1.Enabled := true;
  Button2.Enabled := true;
  Button3.Enabled := true;
end;

//Поток
procedure TForm1.Button3Click(Sender: TObject);
begin
  Button1.Enabled := false;
  Button2.Enabled := false;
  Button3.Enabled := false;

  TimeThread := TTimeThread.Create(true);
  TimeThread.FreeOnTerminate := true;
  TimeThread.Resume;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  CanContinue := false;

  if (TimeThread <> nil) then
  begin
    TimeThread.Terminate;
    TimeThread := nil;

    Button1.Enabled := true;
    Button2.Enabled := true;
    Button3.Enabled := true;
  end;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if (TimeThread <> nil) then
  begin
    TimeThread.Terminate;
  end;
end;

procedure TTimeThread.Execute;
begin
  while not Terminated do 
  begin
    Synchronize(UpdateTime);
  end;
end;

procedure TTimeThread.UpdateTime;
begin
  Form1.Panel1.Caption := DateTimeToStr(Now);
end;

end.



В итоге выяснилось следующее.

В первых двух режимах распределение нагрузки по ядрам процессора (у меня 8 виртуальных) 
выглядит не очень четким, как бы размазанным по всем ядрам, хотя из них можно выделить 
2 или 3 с большей нагрузкой и у одного из этих трёх больше чем у двух других. Графики 
нагрузки в большинстве случаев имеют резкую пилообразную форму, от мнмимума до максимума.
Интегральная нагрузка на процессор 13-14%.

В третем режиме явно видно, что нагружены только 2 ядра из 8ми. Одно ядро имеет 
нагрузку ~30% - очевидно главный поток приложения, втрое ядро нагружено на  ~ 80% - параллелный 
поток приложения, занимающийся опросом времени. Графики нагрузки имеют вид практически 
горизонтальных линий, с небольшим дребезгом.
Интегральная нагрузка на процессор 14-16%, т.е. немного больше чем в первых двух режимах. 

Т.о. отбросив эти 2% (т.е. мою гипотетическюю предвзятость в оценке результатов этого теста), 
можно сделать вывод, что независимо от способа обновления данных на экране, нагрузка 
на процессор не меняется. Более того. Одна и та же нагрузка, распределённая по большему 
количеству ядер, приводит к более равномерному нагреву, снижая локалные 
перегревы процессора, что положительно сказывается на его работе.


Да и вообще, зачем их (процессоры) жалеть? Пусть вкалывают! Они для того и созданы!
Будем сюсюкать с ними - так они нам на шею сядут, и пойдут потом всякие СкайНеты и Генезисы!
Надеюсь, все мы помним, чем это может закончится...

Или не помним  smile 









Это сообщение отредактировал(а) Doga - 4.3.2016, 12:00
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1315 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.