Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.01.2010, 13:22   #1
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию Проблема с главным потоком. Как заставить его ожидать не загружая процессор

Всем привет.
Dpr-файл выглядит примерно слеюдующим образом:

Код:
program someProgramm;
uses
  someForm in 'someForm .pas' {someForm_wnd};

begin
   Application.Title := 'Some application';
   randomize;
   someInValue := 1;
   someStrValue := 'A';
   someBoolValue := true;

   someForm_wnd := tSomeForm_wnd.create(application);
   someForm_wnd.loadSettings;
   
   { ---- прерывание ---- }
   workDone := false;
   repeat
      application.ProcessMessages;
   until workDone;
   { ---- /прерывание ---- }

   someForm_wnd.saveSettings;
   someForm_wnd.free;
end.
Ну, главное в приложении - это иконка в трее и её меню. Оттуда всё управляется.

Проблема в прерывании. То как оно реализованно у меня (временная рнеализация), занимает у проца 99% ресурсов.
Как мне сделать так, что бы остановить выполнение в том месте не нарушая работу программы? Если выставить sleep, то програ замораживается....


Вот. Выкладываю исходник
Вложения
Тип файла: rar someProgramm.rar (299.3 Кб, 19 просмотров)

Последний раз редактировалось Altera; 04.01.2010 в 13:31.
Altera вне форума Ответить с цитированием
Старый 04.01.2010, 13:27   #2
Alex Cones
Trust no one.
Старожил
 
Аватар для Alex Cones
 
Регистрация: 07.04.2009
Сообщений: 6,526
По умолчанию

Где-то здесь на форуме валялся слип, реализованный без зависания. Найти бы его еще. Был бы наилучшим вариантом.

Вот что-то, но, похоже, не оно: http://programmersforum.ru/showpost....33&postcount=5
Что-то еще: http://programmersforum.ru/showpost....8&postcount=12
Вот тут еще пытались извращаться: http://programmersforum.ru/showpost....21&postcount=1
SQUARY PROJECT - НАБОР БЕСПЛАТНЫХ ПРОГРАММ ДЛЯ РАБОЧЕГО СТОЛА.
МОЙ БЛОГ
GRAY FUR FRAMEWORK - УДОБНАЯ И БЫСТРАЯ РАЗРАБОТКА WINAPI ПРИЛОЖЕНИЙ

Последний раз редактировалось Alex Cones; 04.01.2010 в 13:38.
Alex Cones вне форума Ответить с цитированием
Старый 04.01.2010, 14:17   #3
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Цитата:
Сообщение от Alex Cones Посмотреть сообщение
Где-то здесь на форуме валялся слип, реализованный без зависания. Найти бы его еще. Был бы наилучшим вариантом.

Вот что-то, но, похоже, не оно: http://programmersforum.ru/showpost....33&postcount=5
Что-то еще: http://programmersforum.ru/showpost....8&postcount=12
Вот тут еще пытались извращаться: http://programmersforum.ru/showpost....21&postcount=1
Не подходит первый способ во-первых потому, что

Во-вторых, INFINITE не работает.

Да, и это вообще не альтернатива функции sleep. Sleep планирование прекражает на заданное время, а эти просто считает, сколько времени поток выполняется...

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

Последний раз редактировалось Altera; 04.01.2010 в 14:27.
Altera вне форума Ответить с цитированием
Старый 04.01.2010, 14:39   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

так если не надо тормозить основной поток, то и не тормозите его.

если надо чтоб побочный поток сообщил чтото то юзайте или эвенты или сообщения.
если надо в основном ждать результата от побочного...типа Таймаута...
то используем таймер.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 04.01.2010, 14:43   #5
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Ну, может примерчик дадите.
Я до Event-ов ещё не дошёл. Вот есть-же работающий пример
http://programmersforum.ru/attachmen...8&d=1262601057
Altera вне форума Ответить с цитированием
Старый 04.01.2010, 15:03   #6
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

1. Не сохранены правила VCL где Application.CreateForm ? Или где Application.Run ?
2. Раз так, почему бы не глянуть в Application.Run ?
3. Копи паст тех функция (а это GetMessage, TranslateMessage, DispatchMessage, WaitForMessage кажется так)
Вот и все дела. А базара развели нимеряно

p.s. что значит "прерывание" ? Что-то мне не очень нравится данный термин в этой "обстановке". Может "цикл обработки сообщений приложения" ? Или другие формулировки.

А вообще для понимания почему "жрет 99%" вот несколько советов:
1. Приложение Win32 (не консоль и т.п.) работают на сообщениях. Т.е... программа получает/отвечает на сообщения и таким образом производится работа приложения. Когда приложение не отвечает на сообщения то ли обрабатывается какой то участок кода, то оно "зависает". В вашем случае, у вас должно быть окно, которое отвечает на сообщения в трее. А вы зацикливаете своим while и таким образом не даете обрабатывать сообщения.
2. Для "удаления" нагрузки процессора, используется выше упомянутый цикл, таким образом приложение в "бесконечном" цикле получает сообщения и обрабатывает их, если не получает - то windows просто замораживает (не дает квант времени процессора) приложение.

Думаю Вы поняли как это работает, и надеюсь подобных сообщений мы не увидим

Edit:
Почему такой "базар" думаю Вы выразились неверно. Приостановить выполнение программы в том месте, это значит вызов Sleep, WaitForSingleObject и т.п. функции, но это главный поток, в котором работает (как видим в отдельном .pas) ваша "форма" (не знаю почему форма, окно как то привычнее, ну не важно). Следовательно, если в том pas отсутствует Application.Run (ну цикл выше упомянутый) то и приложение не будет работать как я понимаю. Так что имеет смысл вызывать Application.Run или описать цикл руками (он не сложный вовсе, на MSDN примеры есть) и после цикла выполнять следующие действия, которые нужны были после "приостановления".
BOBAH13 вне форума Ответить с цитированием
Старый 04.01.2010, 15:13   #7
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

вот посмотрите, переделал программку под вас

пару комментов, если не успел поток инициироваться то выполняется процедура таймера, если успел то таймер отключается.
Вложения
Тип файла: rar ForAltera.rar (4.0 Кб, 8 просмотров)
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.

Последний раз редактировалось Пепел Феникса; 04.01.2010 в 15:16. Причина: перезалил файл.
Пепел Феникса вне форума Ответить с цитированием
Старый 04.01.2010, 15:35   #8
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

2BOBAH13
Вы как-то сумбурно написали. Я не совсем всё понял.

Вотя вот так реализовал
Код:
While GetMessage(mesg, 0, 0, 0) do
   begin
       TranslateMessage(Mesg);
       DispatchMessage(Mesg);
   end;
Посылаю wm_quit на 0 (postMessage(0, WM_QUIT, 0, 0)). Куда это кстати?
Altera вне форума Ответить с цитированием
Старый 04.01.2010, 15:35   #9
s.Creator
Форумчанин
 
Регистрация: 28.09.2008
Сообщений: 344
По умолчанию

Код:
program someProgramm;

uses
  Forms, Windows,
  someForm in 'someForm.pas' {someForm_wnd};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := False;
  Application.ShowMainForm := False;
  Application.CreateForm(tsomeForm_wnd, someForm_wnd);
  someForm_wnd.Show;
  ShowWindow(Application.handle, SW_HIDE);
  Application.Run;
end.
Код:
unit someForm;

interface

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

type
  TsomeForm_wnd = class(TForm)
    TrayIcon1: TTrayIcon;
    PopupMenu1: TPopupMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    procedure N1Click(Sender: TObject);
    procedure N3Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  someForm_wnd: TsomeForm_wnd;
  workDone: boolean;

implementation

{$R *.dfm}

procedure TsomeForm_wnd.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Action := caNone;
  Hide();
end;

procedure TsomeForm_wnd.N1Click(Sender: TObject);
begin
  Application.Terminate;
end;

procedure TsomeForm_wnd.N3Click(Sender: TObject);
begin
  if isWindowVisible(handle) then
    Hide()
  else
  begin
    Show();
    Application.BringToFront();
  end;
end;

end.
И ничего не тормозит.
Вложения
Тип файла: zip someProgramm.zip (4.4 Кб, 8 просмотров)
s.Creator вне форума Ответить с цитированием
Старый 04.01.2010, 15:38   #10
BOBAH13
Android Developer
Старожил Подтвердите свой е-майл
 
Аватар для BOBAH13
 
Регистрация: 19.02.2007
Сообщений: 3,708
По умолчанию

1. кто мешает в этот самый цикл while GetMessage поставить еще какое то условие ?
2. s. Creator - вы вызвали Application.Run; - это тоже самое что выше упомянутый цикл - поэтому и не тормозит.
BOBAH13 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с потоком в Delphi 2009. S_Yevgeniy Общие вопросы Delphi 2 02.01.2010 13:16
неубиваемый вирус! все антивирусы не находят его! кто знает как его убрать? Yury111 Безопасность, Шифрование 12 05.06.2009 11:19
Нажать на кнопку не загружая страницу Des Работа с сетью в Delphi 1 30.04.2009 16:54
Проблема с потоком Araver Общие вопросы Delphi 4 16.10.2007 04:30