Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2 3 4 5      [все]
 Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Озадачился реализацией данного способа, а опыта работы с потоками вообще нету..(

Попробую словесно описать суть задачи

- Имеется форма и Основная процедура, которая производит какие-то вычисления
- на форме кроме разных полей, имеется Три кнопки: "Заменить", "Пропустить" и "Выход"
- в определенный момент Основной процедуре нужно передать определенные значения или пустить ее по одному из трех направлений, в зависимости от выбора пользователя из трех кнопок.

Сразу скажу - по определенным причинам, применение Диалоговых окон мне не подходит!

Реализацию алгоритмически вижу примерно так:
- внутри Основной процедуры в Осн.потоке пишем бесконечный цикл с анализом внутри трех Флаг-переменных - например Zamena, Propusk, Vihod: Boolean;
- перед этим бесконечным циклом запустить Доп.поток с тремя процедурами обработки клика на соответствующие клавиши, внутри каждой из которых будут меняться Флаг-переменные;
- т.о. получив нужные флаги внутри бесконечного цикла, Осн.поток останавливает Доп.поток и продолжает выполнение Основной процедуры.

По моему - сей алгоритм можно реализовать с помощью потоков!?
Может быть кто либо уже реализовывал его или есть похожие варианты кода?!

P.S. По случаю - поздравляю всех форумчан и Администрацию с наступающим 2018 годом!!!
31 дек 17, 17:09    [21076241]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45049

Bellic
- внутри Основной процедуры в _Осн.потоке_ пишем бесконечный цикл с анализом внутри трех
Флаг-переменных - например *Zamena*, *Propusk*, *Vihod*: *Boolean*;
- перед этим бесконечным циклом запустить _Доп.поток_ с тремя процедурами обработки клика
на соответствующие клавиши, внутри каждой из которых будут меняться Флаг-переменные;

Наоборот. Всем GUI и в том числе кнопками должен заниматься исключительно основной поток.
Дополнительный поток - делает всю продолжительную работу, подчиняясь командам из основного.

Posted via ActualForum NNTP Server 1.5

31 дек 17, 17:45    [21076276]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Dimitry Sibiryakov
Наоборот. Всем GUI и в том числе кнопками должен заниматься исключительно основной поток.
Дополнительный поток - делает всю продолжительную работу, подчиняясь командам из основного.

И что мешает Три процедуры обработки нажатия кнопок написать в отдельном модуле, запустить в Доп.потоке, а в Основном - закрутить в цикле анализ Флагов?
Т.е. как я описал - не получится сделать?
Я просто хочу отказаться от отдельного Диалогового окна в Осн.процедуре, а кнопки разместить на форме!
31 дек 17, 17:56    [21076285]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Я видимо понял!
Создав Доп.поток нужно в нем запустить какую-либо процедуру, а в моем алго - лишь три обработчика нажатия клавиш!?
31 дек 17, 18:06    [21076296]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
а в Основном - закрутить в цикле анализ Флагов?
В основном потоке и так беспрерывно крутится цикл обработки сообщений. Зачем еще один?
31 дек 17, 18:07    [21076298]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
В основном потоке и так беспрерывно крутится цикл обработки сообщений. Зачем еще один?

Цикл анализа реакции выбора Юзера, цикл опроса Флаговых переменных...
31 дек 17, 18:14    [21076310]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Ведь когда вызывается обычное Диалоговое окно - с момента его Вывода на экран и до нажатия кнопок - тоже ведь внутри идет цикл опроса клавиш, по сути!?
31 дек 17, 18:16    [21076314]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Зачем еще один?

YuRock, предложи тогда свой вариант - отказа Диалог.окон и переноса кнопок на основную форму!
31 дек 17, 18:19    [21076316]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Цикл анализа реакции выбора Юзера
Для этого существуют события баттонклики. По сути - орабатываются сообщения wm_command.


Bellic
цикл опроса Флаговых переменных...

Вот его и запихни в доппоток, и при изменении - кидай сообщение основному, что надо что-то изменить в отображении.
31 дек 17, 18:22    [21076321]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Vizit0r
Member

Откуда:
Сообщений: 559
какой-то поток сознания.

Работа делается в отдельном потоке.

Хоткеи срабатывают в основном окне, в обработчике делаются нужные действия с "рабочим" потоком.


Проблема-то в чем?
31 дек 17, 18:23    [21076322]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Ведь когда вызывается обычное Диалоговое окно - с момента его Вывода на экран и до нажатия кнопок - тоже ведь внутри идет цикл опроса клавиш, по сути!?
Это только в VCL такая костыльноглючная технология используется для модальности.
31 дек 17, 18:23    [21076323]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Вот его и запихни в доппоток, и при изменении - кидай сообщение основному, что надо что-то изменить в отображении.

Этого нельзя сделать!
В Основной процедуре открыта куча файлов, задействовано много циклов и переменных, процедура еще выполняется, просто в ОДИН момент нужен выбор юзера, и все!!! Все решается обычным Диалоговым окном!!!
Но мне Диалог не подходит!!!
Необходимо, что бы кнопки принятия решения были на самой форме!
31 дек 17, 18:29    [21076328]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Этого нельзя сделать!
В Основной процедуре открыта куча файлов, задействовано много циклов и переменных, процедура еще выполняется, просто в ОДИН момент нужен выбор юзера, и все!!!
Именно по этому и надо всё это перенести в доп поток, раз много работы.

А выбор юзера сделать перед началом этой работы. Ведь это же бред, когда юзер должен 10 минут сидеть ждать, пока программа его попросит сделать выбор.
31 дек 17, 18:33    [21076335]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Bellic
Этого нельзя сделать!
В Основной процедуре открыта куча файлов, задействовано много циклов и переменных, процедура еще выполняется, просто в ОДИН момент нужен выбор юзера, и все!!!
Именно по этому и надо всё это перенести в доп поток, раз много работы.

А выбор юзера сделать перед началом этой работы. Ведь это же бред, когда юзер должен 10 минут сидеть ждать, пока программа его попросит сделать выбор.

Юзер не будет ждать!
Даже наоборот - ему придется быстро оценивать промежуточные результаты в Эдитах и прочих полях, и нажимать нужную кнопку!
Именно по этому я хочу и отказаться от Диалогового окна, ибо оно закрывает собой часть осн.формы, передвинут его в сторону в ручную - потерять время! Программно разместить например в углу экрана - тоже не вариант - отвлечение внимания юзера и т.п.
31 дек 17, 18:44    [21076347]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Юзер не будет ждать!
Не понятно тогда, зачем другой поток.
31 дек 17, 20:03    [21076462]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Док
Member

Откуда: Казань
Сообщений: 5611
YuRock,

не убеждай его, бесполезно. Клиент должен дозреть.
31 дек 17, 22:35    [21076679]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Парни, видимо меня сильно ругать кое-кто будет сейчас?!..))
Но весь код уместился в Основном модуле и без открытия дополнительных потоков:
+ Тестовый код (палками сильно не бить!..)))
unit Main_Module;

interface

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

type
  TMainForm = class(TForm)
    SButton: TButton;
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    MLabel: TLabel;
    MMemo: TMemo;
    procedure SButtonClick(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
    Flag1, Flag2, Flag3: Boolean;
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation

{$R *.dfm}

//------------------------------------------------------------------------------
procedure TMainForm.Button1Click(Sender: TObject); // Кнопка "Продолжить" счет
begin
     Flag1:=True;
end;
//------------------------------------------------------------------------------
procedure TMainForm.Button2Click(Sender: TObject); // Кнопка "Пропустить" счет
begin
     Flag2:=True;
end;
//------------------------------------------------------------------------------
procedure TMainForm.Button3Click(Sender: TObject); // Кнопка "Остановить" счет
begin
     Flag3:=True;
end;
//------------------------------------------------------------------------------
procedure TMainForm.SButtonClick(Sender: TObject); // Кнопка "Запустить" счет
var
i: Integer;
label
Metka;
begin   MMemo.Lines.Add('Счет запущен');
     while True do
          begin
               for i := 0 to 10 do
                    begin
                         MLabel.Caption := IntToStr(i);
                         Application.ProcessMessages;
                         Sleep(500);
                         if i=5 then
                              begin
                                   MMemo.Lines.Add('Продолжаем цикл? Нажмите одну из Кнопок!');
Metka:                             Application.ProcessMessages; //==============
                                   if Flag1=True then begin
                                        MMemo.Lines.Add('Нажата кн."Продолжить"');
                                        Flag1:=False;
                                        Continue;
                                        end;
                                   if Flag2=True then begin
                                        MMemo.Lines.Add('Нажата кн."Пропустить"');
                                        Flag2:=False;
                                        Break;
                                        end;
                                   if Flag3=True then begin
                                        MMemo.Lines.Add('Нажата кн."Остановить"');
                                        Flag3:=False;
                                        MMemo.Lines.Add('Счет Остановлен!');
                                        Exit;
                                        end;
                                    goto Metka; //==============================
                              end;
                    end;
          end;
end;
//------------------------------------------------------------------------------
end.
Можете меня расстрелять, но Он прекрасно работает!..)))
Возможно будут замечания и к Тестовому коду, к циклам или же к "GOTO"-переходу, но тут важна сама суть - пока процедура "крутится" в цикле между МЕТКА-ми (выделено желтым цветом), анализируя три флага, пользователь приняв решение может нажать одну из 3-х кнопок.

P.S. Поиски в Интернете показали другой вариант - с анализом WM_LBUTTONDOWN, или WM_COMMAND, а потом чтением и анализом Хэндла кнопки... но у меня пока так и не получилось его реализовать.
В этом случае по моему можно было вообще обойтись без отдельных процедур - обработчиков нажатия кнопок!?
3 янв 18, 01:07    [21079598]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Может кто нибудь мне - умственно отсталому человеку объяснить....

На кой чёрт потоки и бесконечные циклы????

Можно же было всем объектам назначить коллбэк один, или вызов доп коллбэка.

И уже там творить все делишки.
3 янв 18, 01:45    [21079614]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
На кой чёрт потоки и бесконечные циклы????
Можно же было всем объектам назначить коллбэк один, или вызов доп коллбэка.
И уже там творить все делишки.

Дополнительного потока в крайнем коде - как видите нету!
А бесконечный цикл (тот что выделен цветом) - в ожидании изменения флагов...

Лучше напишите реально работающий свой вариант с "одним коллбэком"..))
3 янв 18, 01:55    [21079619]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Bellic,

+
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    SButton: TButton;
    Memo1: TMemo;
    procedure AllButtonClick(Sender: TObject);
  private
    SButtonEnebled: Boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.AllButtonClick(Sender: TObject);
  function IndexIArray(const str: string; const arr: TArray<string>): Integer;
  var
    I: Integer;
  begin
    for I := Low(arr) to High(arr) do
      if str.ToLower = arr[I].ToLower then
        exit(I);
  end;

var
  obj: TButton;
begin
  obj := TButton(Sender);
  if not SButtonEnebled then
  begin
    if obj.Name = 'SButton' then
      SButtonEnebled := true
    else
      Memo1.Lines.Add('Кряя. Надо нажать на SButton');
    exit;
  end;

  case IndexIArray(obj.Name, ['Button1', 'Button2', 'Button3']) of
    0:
      begin
        Memo1.Lines.Add('Нажата кн."Продолжить"');
      end;
    1:
      begin
        Memo1.Lines.Add('Нажата кн."Пропустить"');
      end;
    2:
      begin
        Memo1.Lines.Add('Счет Остановлен!');
      end;
  end;
  SButtonEnebled := False;
end;

end.
3 янв 18, 02:07    [21079625]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
alekcvp
Member

Откуда:
Сообщений: 904
Bellic,

Вообще, судя по Sleep(500) - там запланировано выполнение чего-то длительного, поэтому почти всё что в процедуре ".SButtonClick()" нужно вынести в отдельный поток и уже из него анализировать состояние этих флагов.

А вообще, бесконечные циклы, да ещё и со Sleep() в ГУИ потоке - не надо так, пользователи вас за подвисающий интерфейс будут очень долго любить... часто вспоминать... малым загибом... ну и так далее.
3 янв 18, 02:07    [21079626]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
alekcvp
Вообще, судя по Sleep(500) - там запланировано выполнение чего-то длительного
Sleep(500) - это задержка, чисто в тестовом коде, чтоб счет был не таким быстрым!.)))

поэтому почти всё что в процедуре ".SButtonClick()" нужно вынести в отдельный поток и уже из него анализировать состояние этих флагов.
Зачем еще поток? И так ведь все работает?

А вообще, бесконечные циклы, да ещё и со Sleep() в ГУИ потоке - не надо так, пользователи вас за подвисающий интерфейс будут очень долго любить... часто вспоминать... малым загибом... ну и так далее.
Тестовая программа - не зависает, а Пользователи - исключительно только я, ну может с друзьями поделюсь!..))
3 янв 18, 02:32    [21079639]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик, уточните плизз код вот тут:
procedure TForm1.AllButtonClick(Sender: TObject);
  function IndexIArray(const str: string; const arr: TArray<string>): Integer;
  var
    I: Integer;
  begin
    for I := Low(arr) to High(arr) do
      if str.ToLower = arr[I].ToLower then
        exit(I);
        ....

Начинается процедура, затем Функция... а вот
if str.ToLower = arr[I].ToLower then
моя DX вообще не поняла!
У Вас ваш код работает?
3 янв 18, 02:42    [21079644]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Эта функция нужна, что бы найти в массиве индекс элемента. Дабы, что бы по этому индексу обратится к коллекцию case по нужному адресу.


Код полностью рабочий, и никаких задержек не надо.

Хотя я кое что не дописал. Надо ещё в case добавить 3 пункт (3: exit;), дабы при нажатии второй раз кнопки SButton не вылетал флаг в false
3 янв 18, 02:48    [21079648]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Хотя. Ты используешь модуль System.SysUtils ????
3 янв 18, 02:51    [21079649]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
Хотя. Ты используешь модуль System.SysUtils ????

Ну в шапке кода написано - я код свой проверенный, рабочий выложил!

У Вас возможно реализация красивее с CASE выглядит, но я свой Тестовый писал не на выставку, а чтоб понятней было что-куда!
Посему - не придирайтесь так уж!
Для меня важнее было совсем другое!

И всеж - я не понимаю, почему Функция в перемешку с Процедурой???
Может всеж правильнее было так(?):
+
function IndexIArray(const str: string; const arr: TArray<string>): Integer;
  var
    I: Integer;
  begin
    for I := Low(arr) to High(arr) do
      if str.ToLower = arr[I].ToLower then
        exit(I);
  end;
//------------------------------------------------------------------------------
procedure TMainForm.AllButtonClick(Sender: TObject);
var
  obj: TButton;
begin
  obj := TButton(Sender);
  if not SButtonEnebled then
  begin
    if obj.Name = 'SButton' then
      SButtonEnebled := true
    else
      MMemo.Lines.Add('Кряя. Надо нажать на SButton');
    exit;
  end;

  case IndexIArray(obj.Name, ['Button1', 'Button2', 'Button3']) of
    0:
      begin
        MMemo.Lines.Add('Нажата кн."Продолжить"');
      end;
    1:
      begin
        MMemo.Lines.Add('Нажата кн."Пропустить"');
      end;
    2:
      begin
        MMemo.Lines.Add('Счет Остановлен!');
      end;
    3:
      begin
        Exit;
      end;
  end;
  SButtonEnebled := False;
end;
И следующие две строчки - исправьте согласно правил Дэлфи!
+
if str.ToLower = arr[I].ToLower then
        exit(I);
3 янв 18, 03:03    [21079655]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
AllButtonClick - процедура клика на каждую из кнопок?
3 янв 18, 03:06    [21079657]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик, для меня было важно...эээ, попробую выразиться правильным языком:
- важно было то, что передача флагов вполне возможна в Рун-Тайме основного цикла процедуры, при этом процедуры обработки кликов по клавишам отработали как-бы параллельно, выполнив всего лишь одну операцию FlagХ:=True;
Остальной анализ и разветвления - уже опять в основной процедуре цикла!

Все остальное - мелочи вариантов реализации!

И еще - Вы не правильно сделали! Ваши "MMemo.Lines.Add" в CASE отработали в обработчике нажатия клавиш, а Основная процедура осталась без результата нажатия! А для меня именно это нужно было!
Можно конечно вместо "MMemo.Lines.Add" написать "FlagХ:=True;", а уже в основной процедуре анализировать их и выполнять нужную ветку. Но все ж!
3 янв 18, 03:26    [21079667]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Bellic
AllButtonClick - процедура клика на каждую из кнопок?


Верно.

Bellic
а чтоб понятней было что-куда!


А вышло так, что всех запутал. Неправильно реализованной задачей.

Bellic
Функция в перемешку с Процедурой???


Она не в перемешку, она в своей области видимости.
Т.е в общей области недоступна.


Bellic
И следующие две строчки - исправьте согласно правил Дэлфи!


Не понмиаю, что у вас не так. Всё по стандартам record helper for
3 янв 18, 03:28    [21079670]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Bellic,

Зачем нужны какие то флаги???

Почитайте о компоненте ApplicationEvents и установите нормальный обработчик для клавиш нажатых

Или нужна глобальная область??? (Вне программы)
3 янв 18, 03:36    [21079675]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
А вышло так, что всех запутал. Неправильно реализованной задачей.
Я не вижу - в чем запутал всех?
Изначально думал, что придется запускать еще один Доп.Поток, но ситуация решилась и без него!
Что не так?

Она не в перемешку, она в своей области видимости.
Т.е в общей области недоступна.
Понятно! Просто меня несколько это смутило. Ничего что я ее вывел отдельно?

Не понмиаю, что у вас не так. Всё по стандартам record helper for
Картинка с другого сайта.
3 янв 18, 03:41    [21079677]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Bellic
Что не так?


Описанием задачи.

Многие люди, что видят - то и думают, забывая про - то, что ТС сам не знает как реализовать правильно.

К сообщению приложен файл. Размер - 25Kb
3 янв 18, 03:44    [21079680]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
Зачем нужны какие то флаги???
Затем, что получать команду на дальнейшие действия нужно в Рун-Тайме процедуры цикла(обработки инф., подсчета,...)!!!
В реальной процедуре идет обработка информации из нескольких открытых файлов, юзеру выводится исходная инфа и предлагается сделать свой выбор - Обработать, Пропустить Шаг или Выйти.
Сначало я заюзал Диалоговое окно, но с ним неудобно и криво работать!
Поэтому искал методу управления внутри процедуры с кнопок формы, но в том же Рун-Тайме, не закрывая файлов и не теряя значений кучи переменных.
Так - понятней?
А Тестовый код считаю максимально приближенным к Реальному...

Почитайте о компоненте ApplicationEvents и установите нормальный обработчик для клавиш нажатых
А вот за подсказку - при много благодарен! Но похоже изучать и смотреть - пригодиться ли оно мне - уже буду утром!..)))
3 янв 18, 03:55    [21079684]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
важно было то, что передача флагов вполне возможна в Рун-Тайме основного цикла процедуры, при этом процедуры обработки кликов по клавишам

Это не основной цикл, а дополнительный и полностью бессмысленный.
Основной крутится внутри Application.Run - нормальный цикл, ожидающий события получения сообщения, а не хрень со Sleep и ProcessMessages.

Тебе не нужны ни флаги ни цикл. Назначь кнопкам один обработчик (в object inspector на вкладке events) - это и будет твоя "процедура".
И установи им разное значение свойства Tag (в object inspector на вкладке properties). Это и будут твои флаги.

И в этой своей "основной процедуре" просто пиши
if TButton( Sender ).Tag = 2 then...
3 янв 18, 04:35    [21079695]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Не благодари. Поставь компонент ApplicationEvents и на него событие onMessage

+
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.AppEvnts;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Button3: TButton;
    SButton: TButton;
    Memo1: TMemo;
    ApplicationEvents1: TApplicationEvents;
    procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
  private
    SButtonEnebled: Boolean;
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);

var
  ActiveHandle, idx: NativeInt;
  str: string;
  function IndexIArray(const str: Integer; const arr: TArray<Integer>): Integer;
  var
    I: Integer;
  begin
    for I := Low(arr) to High(arr) do
    begin
      ActiveHandle := arr[I];
      if str = ActiveHandle then
        exit(I);
    end;
    ActiveHandle := 0;
  end;

begin
  if Msg.message = 513 then
  begin
    idx := IndexIArray(Msg.hwnd, [Button1.Handle, Button2.Handle,
      Button3.Handle, SButton.Handle]);

    if not SButtonEnebled then
    begin
      if ActiveHandle = SButton.Handle then
        SButtonEnebled := true
      else
        Memo1.Lines.Add('Кряя. Надо нажать на SButton');
      exit;
    end;

    case idx of
      0:
        begin
          Memo1.Lines.Add('Нажата кн."Продолжить"');
        end;
      1:
        begin
          Memo1.Lines.Add('Нажата кн."Пропустить"');
        end;
      2:
        begin
          Memo1.Lines.Add('Счет Остановлен!');
        end;
      3:
        exit;
    end;
    SButtonEnebled := false;
  end
  else if Msg.message = 257 then
  begin
    Memo1.Lines.Add('Нажата кнопка: ' + chr(Msg.wParam));
  end;

end;

end.
3 янв 18, 04:40    [21079701]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Небольшой фикс
   end;
    ActiveHandle := -1;
  end;
3 янв 18, 05:30    [21079712]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Vizit0r
Member

Откуда:
Сообщений: 559
Няшик, ты знаешь толк в извращениях.
Массив, поиск в нем по имени...и все это вместо того, чтобы трем кнопкам проставить Tag от нуля до двух, и сверяться с ним.
3 янв 18, 10:28    [21079786]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Няшику, по последнему коду: TArray<Integer>, надежнее массив NativeUInt'ов, быстрее и проще TArray.BinarySearch, хотя в случае четырёх членов, думаю, пофиг.
YuRock
Это не основной цикл, а дополнительный и полностью бессмысленный.

Я так понимаю, что у него всё крутится в одном потоке и ему нужно как-то 'придержать' работу кода до нажатия на кнопки, которые находятся на форме.
3 янв 18, 10:54    [21079809]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Vizit0r,

+1, проще case по тэгу. для четырёх то кнопок )
3 янв 18, 10:55    [21079811]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Много думал, почему няшик так хитро делает. То названия, то зачем-то хендлы (причем не совсем верно - handle не integer ни разу, можно нарваться на глюки). Почему не просто tag? Боюсь, няшик, что картинку, которую ты постил, можешь применить и к себе
3 янв 18, 11:02    [21079818]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Ладно, за деревьями леса не видно, как обычно :) Мой хрустальный шар выдал следующее. ТСу нужно что-то считать. Потом остановить счет, дождаться реакции нажатия на кнопку на этой же форме, где идёт расчет, и дальше продолжить, возможно в зависимости от того, что нажали. Если 'расчет' довольно быстрый, то, думаю, можно попробовать основным потоком обойтись. В общем - ждём пока нормального описания того, что нужно. Иначе можно долго гадать.
3 янв 18, 11:10    [21079823]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
Не благодари. Поставь компонент ApplicationEvents и на него событие onMessage
idx := IndexIArray(Msg.hwnd, [Button1.Handle, Button2.Handle,
      Button3.Handle, SButton.Handle]);
[dcc32 Error] Main_Module.pas(166): E2010 Incompatible types: 'System.TArray<System.Integer>' and 'Set' !!!

Возможно я не прав, Няшик, а Ваша процедура через себя все События Windows будет пропускать?
Может для начало нужно было отловить нажатие левой кнопки мыши (WM_LBUTTONDOWN), а потом проанализировать - а не по нужной ли кнопке мацнул юзер? Или из WM_COMMAND можно сразу Хэндл кнопки узнать?!
Я не иронизирую вовсе, просто в этих делах мало пока понимаю! Посему - убедительно прошу, проверяйте свой код перед публикацией и желательно с компиляцией - не хочется искать ошибки в чужих творениях!
Кстати - Вы привели обработчик событий, а что же в это время будет делать основной цикл в Осн.процедуре? Я про вот это имел ввиду:
while True do
          begin
               for i := 0 to 10 do
                     begin
                        ...
                     end;
          end;

makhaon
Я так понимаю, что у него всё крутится в одном потоке и ему нужно как-то 'придержать' работу кода до нажатия на кнопки, которые находятся на форме.
Браво!!! Совершенно верно! я вроде так и объяснял, не вдаваясь в подробности, даже Тестовый код приближенный к реальному воспроизвел!
Только маленькое уточнение! - Не "придержать работу", а после выбора юзером - продолжить выполнение по алгоритму, пропустить его часть или выйти с сохранением результата, полученного на это время.

makhaon
ТСу нужно что-то считать. Потом остановить счет, дождаться реакции нажатия на кнопку на этой же форме, где идёт расчет, и дальше продолжить, возможно в зависимости от того, что нажали. Если 'расчет' довольно быстрый, то, думаю, можно попробовать основным потоком обойтись.
И тут - Ваш хрустальный шар правильно предсказал!..)))

makhaon
В общем - ждём пока нормального описания того, что нужно. Иначе можно долго гадать.
Уже и не знаю, как упростить описание "Задания", что бы не грузить лишней информацией!? Ну не всю же процедуру сюда реальную копировать?
Есть предложение - давайте я попробую еще раз сформулировать задачу, но пусть это будет уже Новый топик, ибо этот звучит как "Обработка нажатия трех кнопок в параллельном потоке", а о потоках вроде как уже не говорим!
Модераторы могут возмутиться!
Иль тут продолжить?
3 янв 18, 12:06    [21079883]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Vizit0r
Массив, поиск в нем по имени...и все это вместо того, чтобы трем кнопкам проставить Tag от нуля до двух, и сверяться с ним.

Можно даже проще.
if Sender = Button2 then
3 янв 18, 12:13    [21079892]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Уже и не знаю, как упростить описание "Задания", что бы не грузить лишней информацией!? Ну не всю же процедуру сюда реальную копировать?

Нет, процедуру не надо уже, упаси бог. Нужно "Задание" сюда скопировать.
3 янв 18, 12:16    [21079902]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Bellic,

Понятно, я так и думал. Можно попробовать сделать так:
1. Считаем всё до момента необходимости выбора.
2. Включаем visible, либо, лучше, делаем enable кнопкам.
3. Ждём безо всяких циклов когда юзер нажмёт какую-то кнопку.
4. В обработчиках OnClick кнопок развешиваем остальные куски кода, в зависимости от того, что нажмут.
Согласен, что батонокидательство. Но, думаю, в этом случае, допустимое.
3 янв 18, 12:18    [21079915]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Можно даже проще.
if Sender = Button2 then
Не пойму - зачем лишние проверки и массивы?
Чем плох код из этого сообщения?
Тем, что на каждой из кнопок - мизерный обработчик висит? - Возможно можно написать и Общий обработчик для трех кнопок, но тогда внутри него придется развернуть анализ...(
Или Три флага смущают?
3 янв 18, 12:22    [21079931]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
но тогда внутри него придется развернуть анализ

Это именно этот анализ:
if Flag2=True then begin

И, это, еще так можно писать, чтоб точно враги не догадались:
if (Flag2=True)=True then begin


(это я к тому, что булево значение уже не надо сравнивать с True, вообще не надо ни с чем сравнивать, оно готово для использования в условиях - if Flag2 then)
3 янв 18, 12:34    [21079956]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Bellic,

Плох Application.ProcessMessages + Sleep. Тем, что занимает ресурсы, сильно ухудшает отзывчивость программы, заставляя основной поток спать, потенциально может привести к трудноуловимым багам.
3 янв 18, 12:34    [21079958]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
зачем лишние проверки и массивы?

Т.ч. проверок столько же, только лишних переменных, обработчиков и логики меньше.
А зачем массивы - я тоже не знаю.
3 янв 18, 12:34    [21079960]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
автор
но тогда внутри него придется развернуть анализ


Вот весь анализ

case (Sender as TComponent).Tag of:
 0: {делаем что-то};
 1: {делаем что-то};
 2: {делаем что-то}; 
end;


Тэги в кнопках проставить только.
3 янв 18, 12:37    [21079963]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
makhaon
Bellic,
Понятно, я так и думал. Можно попробовать сделать так:
1. Считаем всё до момента необходимости выбора.
2. Включаем visible, либо, лучше, делаем enable кнопкам.
3. Ждём безо всяких циклов когда юзер нажмёт какую-то кнопку.
4. В обработчиках OnClick кнопок развешиваем остальные куски кода, в зависимости от того, что нажмут.
Согласен, что батонокидательство. Но, думаю, в этом случае, допустимое.

Из всего этого все понятно и так есть и будет!
Уже давно пользуюсь "Enabled кнопкам"..))
...
А теперь хотелось бы увидеть Ваше решение 3-го пункта!!!
...
У меня до этого было примерно так (Это и было Вашим 3-м пунктом! - Ожидание!):
Rez := MessageDlg('Найдена фраза для замены. Заменить?',
           mtConfirmation, [mbYes, mbNo, mbCancel], poDefault);
Ну а после этого - анализ ответа (Rez) и соответственно свой код.

Но этот модальный Диалог мне мешал:
1. Если не позицировать его - мешал анализу данных других полей на форме;
2. Если убрать куда-нибуть в угол - как то не "Айс";
3. Модальность не позволяла при необходимости скопировать инфу из Мэмо или Эдитов;
4. ...

Нужно было как то избавиться от Диалога, воспроизведя кнопки на форме и смоделировать режим "Ожидания"... Вот!

P.S. Было еще одно решение, но в силу опять же "модальности", оно тоже было отброшено!
Это было маленькая форма с этими тремя кнопками, без шапки и боковых границ, ... она позиционировалась в нужное место на Осн.форме и кнопки выглядели, как будто принадлежащие Осн.форме...
В общем - это к делу не относится!..))
3 янв 18, 12:46    [21079978]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Да, я уже понял твою проблему.

автор
А теперь хотелось бы увидеть Ваше решение 3-го пункта!!!

Решение без кода :) Просто - ждём до тех пор, пока юзер что-то нажмёт. Как только нажал - считаем дальше. Совсем не обязательно счетную процедуру делать в пределах одного метода.
3 янв 18, 12:52    [21079988]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
makhaon
(это я к тому, что булево значение уже не надо сравнивать с True, вообще не надо ни с чем сравнивать, оно готово для использования в условиях - if Flag2 then)
я прекрасно об этом знаю! Это - мелочи Тестового кода, не стоило в это место меня носом тыкать!..)))
makhaon
Плох Application.ProcessMessages + Sleep

Я уже ответил по этому поводу, читайте выше!
Sleep - только лишь тут в Тестовом коде, дабы замедлить счет от 0 до 5 и от 5 до 10!
Application.ProcessMessages - для того, чтоб опять таки в Тестовом коде в шапке формы не видеть "Не отвечает".

Вот весь анализ

case (Sender as TComponent).Tag of:
 0: {делаем что-то};
 1: {делаем что-то};
 2: {делаем что-то}; 
end;
Тэги в кнопках проставить только.
Мне эта идея больше нравится, чем массивы!..)))
3 янв 18, 13:01    [21080004]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
makhaon
Да, я уже понял твою проблему.

Решение без кода :) Просто - ждём до тех пор, пока юзер что-то нажмёт. Как только нажал - считаем дальше. Совсем не обязательно счетную процедуру делать в пределах одного метода.

Я не понимаю выражения "просто ждем"!
В варианте с Диалоговым окном - понятно было в каком месте это ожидание!
А как в Вашем варианте заставить, к примеру цикл, "просто ждать" ну скажем в своем i/2-состоянии?
3 янв 18, 13:10    [21080010]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Извиняюсь, что влезаю опять.

Bellic
Я не понимаю выражения "просто ждем"!

Ну есть 2 варианта:
1. "Ждем" - это ждем наступления события;
2. "Просто ждем" - вообще ничего не делаем.

Bellic
заставить, к примеру цикл, "просто ждать"

Никак. Цикл не нужен просто. Скорее всего, не смотря ни на что. Хотя то, что нужно, до сих пор тайна, но я уверен, что не нужен, и хватит одного цикла обработки сообщений (который и так есть), который и события действий пользователя обрабатывает.
Просто ничего не нужно. Нужно вызвать какую-то процедуру при запуске программы и затем вызывать какие-то процедуры при нажатии на кнопки, всё. Всё, пока не будет известна задача.
3 янв 18, 13:23    [21080026]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Vizit0r, makhaon. Как вы tag то в OnMessage отловите ???? Я первым делом попытался это сделать, и не было ничего в структуре tagMSG

Насчёт handle да, надо было NativeUInt ... Была глубокая ночь, под утром.


Bellic
Может для начало нужно было отловить нажатие левой кнопки мыши (WM_LBUTTONDOWN), а потом проанализировать - а не по нужной ли кнопке мацнул юзер? Или из WM_COMMAND можно сразу Хэндл кнопки узнать?!


У меня так и реализована, проверка нажатие кнопки. + Проверка, на какую нажали по handle
3 янв 18, 13:26    [21080032]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Циклы к слову вообще не нужны, уже есть ApplicationEvents

Можно и так сделать ведь
+
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  if Msg.message = 513 then
  begin
    if not SButtonEnebled then
    begin
      if Msg.hwnd = SButton.Handle then
        SButtonEnebled := true
      else
        Memo1.Lines.Add('Кряя. Надо нажать на SButton');
      exit;
    end;

    if Msg.hwnd = Button1.Handle then
      Memo1.Lines.Add('Нажата кн."Продолжить"')
    else if Msg.hwnd = Button2.Handle then
      Memo1.Lines.Add('Нажата кн."Пропустить"')
    else if Msg.hwnd = Button3.Handle then
      Memo1.Lines.Add('Счет Остановлен!')
    else
      exit;

    SButtonEnebled := false;
  end
  else if Msg.message = 257 then
  begin
    Memo1.Lines.Add('Нажата кнопка: ' + chr(Msg.wParam));
  end;
end;
3 янв 18, 13:34    [21080042]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock, Вы похоже так "Задачу" и не поняли в отличие от makhaon!...(((
А знаете почему? - Потому, что мыслите стандартно! - По Вашему, раз есть Обработчики событий, то и целостный код нужно "поделить" между ними и заново переписать весь алгоритм!?

Предприму "крайнюю" попытку, лично для Вас на тестовом коде сымитировать и описать Задачу:
(только слезно прошу - не переделывать цикл под свое мышление! - Это всего лишь имитация Реального кода!)
+ Имеется код с Диалогом
unit Main_Module;

interface

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

type
  TMainForm = class(TForm)
    SButton: TButton;
    MLabel: TLabel;
    procedure TestCode(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MainForm: TMainForm;

implementation
{$R *.dfm}
//------------------------------------------------------------------------------
procedure TMainForm.TestCode(Sender: TObject);
var
  i: Integer;
  Rez : Integer;
label
  M;
begin
     while True do
          begin
  M:           Rez := 0;
               for i := 0 to 1000 do
                    begin
                         MLabel.Caption := IntToStr(i);
                         // Эти два оператора - чисто для замедления счета!
                         Application.ProcessMessages;
                         Sleep(5);

                         if i=500 then
                              Rez := MessageDlg('Досчитали до 500. Продолжить?',
                                   mtCustom, mbYesNoCancel, 0);
                                   // bmYes - Продолжить
                                   // mbNo - Пропустить
                                   // mbCancel - Выйти
                         case Rez of
                              6:   Continue; // Продолжаем счет от 500 до 1000
                              7:   goto M;   // Пропускаем и начинаем с начала
                              2:   Exit;    // Прерываем счет
                         end;
                    end;
          end;
end;
end.

Задача: Избавиться от Диалогового окна и не нарушая алгоритма процедуры и не разваливая ее на 3-4 отдельных, "перенести" три кнопки на форму.
3 янв 18, 14:27    [21080108]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
YuRock, Вы похоже так "Задачу" и не поняли в отличие от makhaon!...(((

Можно на ты? Так проще.
Bellic
не разваливая ее на 3-4 отдельных

Почему ты так боишься упрощения кода?
3 янв 18, 14:32    [21080120]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Да.. Если нужен цикл, то используй таймер. Он уже как бы почти в потоке работает. И выполняй код без тормозов.

Вот его останавливай - запускай, задавай время через сколько он будет срабатывать.
3 янв 18, 14:42    [21080134]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Предприму "крайнюю" попытку, лично для Вас

Спасибо, конечно. Но этот "крайний" код не работоспособен. Ведь TestCode() даже не вызывается нигде.
Если она вызывается в FormCreate и будет "крутиться" постоянно, то действительно нужен отдельный поток. В этом случае надо четко определить состояния результата твоего расчета и когда будет какой-то результат - посылать об этом сообщение главному потоку и ожидать от него команды на продолжение.

Но я в этом до сих пор, мягко говоря, не уверен. Я уже 2 раза просил объяснить задачу, а не показывать "тестовый код". Русским языком объяснить, что тебе заказчик (или препод или кто там) заказал сделать. Твои "тестовые коды" только уводят всё дальше и дальше от понимания задачи не только окружающих, но и тебя.
3 янв 18, 14:42    [21080135]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Няшик
Да.. Если нужен цикл, то используй таймер. Он уже как бы почти в потоке работает. И выполняй код без тормозов.

Массивы ввели, теперь таймер. Еще надо COM использовать и дотнетовскую библиотеку прикрутить через прослойку-сервер приложений. Для упрощения.
3 янв 18, 14:44    [21080139]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
YuRock,

Таймер то лучше использовать, чем for с sleep и ProcessMessages

Это правильный вариант (Таймер) И самый простой

... Я думаю пользователь делает игру для развития умственных способностей, выполняя действий подсчёт чего - либо то, и нахождения совпадений и так далее

Судя по последнему примеру
3 янв 18, 14:48    [21080151]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Почему ты так боишься упрощения кода?

YuRock, зачем этот вопрос?
Я ведь технически грамотно вроде поставил задачу на Тестовом примере?

Или ты хочешь услышать - что делается в Реальной процедуре, или даже увидеть?
я ведь уже немного писал о ней!
Там открыто на чтение 2 файла, идет цикл побайтового их сравнения (автоматом), и при особых ситуациях требуется Решение оператора, в 3-й файл попадают результаты, на форме - 4 текстовых эдита с промежуточными результатами и еще Окошко типа как в Hex-редакторе (Оффсеты, Нех-значения и литеральное соответствие).
И ты хочешь эти открытые файлы и процедуры взять и закрыть и потом опять их дергать открывание-закрывание и передачей переменных между процедурами?
Нет уж!!!

Кстати - есть аналогичная и Автоматическая процедура, которая отрабатывает от начала и до конца без "тычков" оператора.
Ручная процедура была просто скопирована с Автоматической и дополнена Диалоговым окном и обработкой его результатов.
(Возможно можно будет в будущем оба варианта (Авто и Ручной) сделать для экономии в одной процедуре, но это сейчас не важно.)
3 янв 18, 14:53    [21080156]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Что мешает открыть файл в одном месте - держать на него ссылку ???

Даже если мы и закрываем файл, мы можем запомнить на какой позиции чтения было закрыто. И при открытии сделать offset ....


Или ты читаешь файл целиком????
3 янв 18, 15:09    [21080175]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
ИЗ тс-а вытягивают инфу силой, вымогая - а он суёт свои тестовые коды, где нет подробности информации .... А он думает, что все должны понять его мысль - которую он и сам не может реализовать
3 янв 18, 15:10    [21080176]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Спасибо, конечно. Но этот "крайний" код не работоспособен. Ведь TestCode() даже не вызывается нигде.
TestCode() вызывается единственной кнопкой на форме SButton: TButton;
Неужели это трудно увидеть или догадаться, раз есть Одна процедура, то ее нужно запустить!
Тестовый код - полностью работоспособен!!! - Я же не на бумажке рисую, как Няшик с ошибками!?..)))
(Вот ссылка на полный исходник Теста)
А это - Форма:
+ Текст файла формы "Main_Module.dfm":
object MainForm: TMainForm
  Left = 0
  Top = 0
  Caption = 'MainForm'
  ClientHeight = 77
  ClientWidth = 281
  Color = clAppWorkSpace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
  object MLabel: TLabel
    Left = 139
    Top = 8
    Width = 7
    Height = 25
    Font.Charset = DEFAULT_CHARSET
    Font.Color = clAqua
    Font.Height = -21
    Font.Name = 'Tahoma'
    Font.Style = []
    ParentFont = False
  end
  object SButton: TButton
    Left = 102
    Top = 40
    Width = 75
    Height = 25
    Caption = #1047#1072#1087#1091#1089#1090#1080#1090#1100
    TabOrder = 0
    OnClick = TestCode
  end
end

YuRock
Я уже 2 раза просил объяснить задачу, а не показывать "тестовый код". Русским языком объяснить, что тебе заказчик (или препод или кто там) заказал сделать. Твои "тестовые коды" только уводят всё дальше и дальше от понимания задачи не только окружающих, но и тебя.

Меня лично никто никуда не уводит, и вы тоже не убегайте!.)))
Я Задачу поставил - если хотите, решите ее с моими поставленными условиями!
Не можете понять или не хотите тратить время - воля Ваша!

Кратко: Задача, просто избавиться в теле цикла от Диалогового окна с 3-мя кнопками, создав аналогичные кнопки на самой форме, при этом не делить цикл на части(процедуры). Куда уже проще описать без тестового кода?
3 янв 18, 15:15    [21080183]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
Что мешает открыть файл в одном месте - держать на него ссылку ???
Даже если мы и закрываем файл, мы можем запомнить на какой позиции чтения было закрыто. И при открытии сделать offset ....
Или ты читаешь файл целиком????
Запомнить можно все и не важно как читается файл(в Memory, TByte, ... или FileStream) - я уже написал, что задача "избавиться от Диалогового окна", не переделывая всю процедуру... Читай выше!
3 янв 18, 15:28    [21080203]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Я ведь технически грамотно вроде поставил задачу на Тестовом примере?

Мне уже настолько надоело, что стало интересно . Вот это - то, что тебе нужно?
Твой тестовый пример на потоке (возможно есть баги, но на глаз я не вижу):
+
unit Unit1;

interface

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

const
  WM_THREAD_UPDATE = WM_USER + 1;
  WM_THREAD_REQUEST = WM_USER + 2;
  WM_THREAD_STOP = WM_USER + 3;

type
  TTestThread = class( TThread )
  private
    FWindowHandle: HWND;
    FWaitEvent: TSimpleEvent;
    FContinueFunc: TMsgDlgBtn;
  protected
    procedure Execute; override;
  public
    constructor Create( AWindowHandle: HWND );
    destructor Destroy; override;

    procedure ContinueCommand( AContinueFlag: TMsgDlgBtn );
  end;

  TForm1 = class(TForm)
    btnRestart: TButton;
    btnContinue: TButton;
    btnStop: TButton;
    Label1: TLabel;
    btnSkip: TButton;
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    procedure btnRestartClick(Sender: TObject);
    procedure btnContinueClick(Sender: TObject);
    procedure btnStopClick(Sender: TObject);
    procedure btnSkipClick(Sender: TObject);
  private
    FThread: TTestThread;

    procedure OnThreadUpdate( var Msg: TMessage ); message WM_THREAD_UPDATE;
    procedure OnThreadRequest( var Msg: TMessage ); message WM_THREAD_REQUEST;
    procedure OnThreadStop( var Msg: TMessage ); message WM_THREAD_STOP;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  btnRestart.Enabled := True;
  btnContinue.Enabled := False;
  btnSkip.Enabled := False;
  btnStop.Enabled := False;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FThread.Free;
end;

procedure TForm1.OnThreadUpdate( var Msg: TMessage );
begin
  Label1.Caption := IntToStr( Msg.WParam );
end;

procedure TForm1.OnThreadRequest( var Msg: TMessage );
begin
  btnContinue.Enabled := True;
  btnSkip.Enabled := True;
  btnStop.Enabled := True;
end;

procedure TForm1.OnThreadStop( var Msg: TMessage );
begin
  FreeAndNil( FThread );
  btnRestart.Enabled := True;
end;

procedure TForm1.btnRestartClick(Sender: TObject);
begin
  btnRestart.Enabled := False;
  FThread.Free;
  FThread := TTestThread.Create( Handle );
end;

procedure TForm1.btnContinueClick(Sender: TObject);
begin
  btnContinue.Enabled := False;
  btnSkip.Enabled := False;
  btnStop.Enabled := False;
  FThread.ContinueCommand( mbYes );
end;

procedure TForm1.btnSkipClick(Sender: TObject);
begin
  btnContinue.Enabled := False;
  btnSkip.Enabled := False;
  btnStop.Enabled := False;
  FThread.ContinueCommand( mbNo );
end;

procedure TForm1.btnStopClick(Sender: TObject);
begin
  btnContinue.Enabled := False;
  btnSkip.Enabled := False;
  btnStop.Enabled := False;
  FThread.ContinueCommand( mbCancel );
end;

constructor TTestThread.Create( AWindowHandle: HWND );
begin
  FWindowHandle := AWindowHandle;
  FWaitEvent := TSimpleEvent.Create;
  inherited Create( False );
end;

destructor TTestThread.Destroy;
begin
  Terminate;
  FWaitEvent.SetEvent;
  inherited;
  FWaitEvent.Free;
end;

procedure TTestThread.ContinueCommand( AContinueFlag: TMsgDlgBtn );
begin
  FContinueFunc := AContinueFlag;
  FWaitEvent.SetEvent;
end;

procedure TTestThread.Execute;
var
  i: Integer;
begin
  try
    repeat
      for i := 0 to 1000 do begin
        SendMessage( FWindowHandle, WM_THREAD_UPDATE, i, 0 );
        FWaitEvent.WaitFor( 5 );
        if Terminated then
          Exit;

        if i = 500 then begin
          SendMessage( FWindowHandle, WM_THREAD_REQUEST, 0, 0 );
          FWaitEvent.WaitFor( INFINITE );
          if Terminated then
            Exit;

          FWaitEvent.ResetEvent;
          case FContinueFunc of
            mbYes: Continue; // Продолжаем счет от 500 (на самом деле от 501) до 1000
            mbNo: Break; // Пропускаем и начинаем с начала
            else {mbCancel} // Прерываем счет
              Exit;
          end;
        end;
      end;
    until Terminated;
  finally
    PostMessage( FWindowHandle, WM_THREAD_STOP, 0, 0 );
  end;
end;

end.

(Во вложении - проект. Играйся.)


К сообщению приложен файл (Test.zip - 2Kb) cкачать
3 янв 18, 15:33    [21080208]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
ИЗ тс-а вытягивают инфу силой, вымогая - а он суёт свои тестовые коды, где нет подробности информации .... А он думает, что все должны понять его мысль - которую он и сам не может реализовать

Знаешь, становится похожим на короля из Мультика "Бременские музыканты", который просто хотел на завтрак съесть кусочек масла, а придворные из этого желания сделали проблему!

Я привожу Вам всем простую Задачу (как просто кусочек Масла), а Вы требуете какие то подробности(может быть нужна инфа по Жирности масла, дате его изготовления, сроке годности или производителе?), которые принесут еще больший головняк и Вам и мне! Нафига спрашивается?
Или Вы просто насмехаетесь надо мной?
3 янв 18, 15:36    [21080211]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Мне уже настолько надоело, что стало интересно . Вот это - то, что тебе нужно?
Твой тестовый пример на потоке (возможно есть баги, но на глаз я не вижу):

Ругнулось при открытие на отсутствие "Project.res", но пересоздала его...)
У меня все работает, согласно "Задаче"... Класс!!! Но лично мне еще "вкурить" это все нужно!
Единственное на взгляд - очень много процедур добавилось, но это не критично, я не придираюсь!
Ну и вопрос - в принципе, обязателен ли тут был Поток?
Без него - какие варианты еще есть?
3 янв 18, 15:51    [21080229]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
очень много процедур добавилось

Процедуры btnContinueClick, btnSkipClick, btnStopClick легко превращаются в одну с помощью Tag
Bellic
Ну и вопрос - в принципе, обязателен ли тут был Поток?

Любую задачу можно решить в одном потоке. Иногда это идеальный вариант. Но ты же хранишь условие задачи в секрете, откуда я знаю.
Bellic
Без него - какие варианты еще есть?

Только такие, которые будут тормозить интерфейс.
3 янв 18, 15:59    [21080236]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Dmitri Krizhanovski
Member

Откуда:
Сообщений: 477
Bellic,

Вот так я бы насписАл надцать лет назад и не парился:
+

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    bnRun: TButton;
    MLabel: TLabel;
    bnContinue: TButton;
    bnReRun: TButton;
    bnCancel: TButton;
    procedure bnRunClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure bnContinueClick(Sender: TObject);
    procedure bnReRunClick(Sender: TObject);
    procedure bnCancelClick(Sender: TObject);
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
  private
    FProcessing: Boolean;
    FProcessIndex: Integer;
    { Private declarations }
    {
      AFlag
        0 - Run
        1 - Continue
        2 - ReRun
        3 - Cancel
    }
    procedure Processing(AFlag: Integer);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.bnCancelClick(Sender: TObject);
begin
  Processing(3);
end;

procedure TForm1.bnContinueClick(Sender: TObject);
begin
  Processing(1);
end;

procedure TForm1.bnReRunClick(Sender: TObject);
begin
  Processing(2);
end;

procedure TForm1.bnRunClick(Sender: TObject);
begin
  Processing(0);
end;

procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
  CanClose := not FProcessing;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  bnContinue.Enabled := False;
  bnReRun.Enabled := False;
  bnCancel.Enabled := False;
end;

procedure TForm1.Processing(AFlag: Integer);
var
  i: Integer;
begin
  {
      AFlag
        0 - Run
        1 - Continue
        2 - ReRun
        3 - Cancel
  }
  case AFlag of
  0,2:
      begin
        FProcessIndex := 0;
        bnRun.Enabled := False;
        bnContinue.Enabled := False;
        bnReRun.Enabled := False;
        bnCancel.Enabled := False;
      end;
  1:
      begin
        bnContinue.Enabled := False;
        bnReRun.Enabled := False;
        bnCancel.Enabled := False;
      end;
  3:
      begin
        bnRun.Enabled := True;
        bnContinue.Enabled := False;
        bnReRun.Enabled := False;
        bnCancel.Enabled := False;
        Exit;
      end;
  end;

  FProcessing := True;
  try
    for i := FProcessIndex to 1000 do
    begin
      FProcessIndex := i + 1;

      MLabel.Caption := IntToStr(i);
      // Эти два оператора - чисто для замедления счета!
      Application.ProcessMessages;
      Sleep(5);

      if i = 500 then
      begin
        bnContinue.Enabled := True;
        bnReRun.Enabled := True;
        bnCancel.Enabled := True;
        flashwindow(Handle, true);
        Exit;
      end;
    end;
  finally
    FProcessing := False;
  end;

  if i = 1000 then
  begin
    bnRun.Enabled := True;
    bnContinue.Enabled := False;
    bnReRun.Enabled := False;
    bnCancel.Enabled := False;
  end;
end;

end.
до тех пор, пока пользователи не стали бы жаловаться.
А сейчас что-то как у 21080208
3 янв 18, 16:07    [21080245]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Freedoom
Guest
Bellic, на форму кидаешь панельку с тремя (или сколько нужно кнопками), делаешь её не активной, в фомре объявляешь переменную, например FRes: integer, а вместо Rez := MessageDlg вставляешь код
Panel.Enable := True;
FRes := 0;
while FRes = 0 do Application.ProcessMessages;
Panel.Enable := False;
При этом в обработчиках кнопок FRes присваиваешь нужное значение.
3 янв 18, 16:10    [21080247]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Процедуры btnContinueClick, btnSkipClick, btnStopClick легко превращаются в одну с помощью Tag

Это понятно:
+
procedure TForm1.ContinueSkipStopClick(Sender: TObject);
begin
  btnContinue.Enabled := False;
  btnSkip.Enabled := False;
  btnStop.Enabled := False;
  case (Sender as TComponent).Tag of
      1: FThread.ContinueCommand( mbYes );
      2: FThread.ContinueCommand( mbNo );
      3: FThread.ContinueCommand( mbCancel );
  end;
end;
3 янв 18, 16:15    [21080251]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 52396
Блог
Bellic
Можете меня расстрелять, но Он прекрасно работает!..)))

Попробуй, пока он работает, нажать, скажем, крестик в правом верхнем углу.
3 янв 18, 16:57    [21080300]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Freedoom, очень интересно получилось! Класс!
(Нет явного цикла ожидания, доп.потока и TAG использован по совету парней!)
Архив проекта прилагается...)
3 янв 18, 17:02    [21080312]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Freedoom, очень интересно получилось! Класс!
(Нет явного цикла ожидания, доп.потока и TAG использован по совету парней!)

Жаль только электроэнергии за нагрузку процессора в 100% и тормозов компьютера из-за этого.
3 янв 18, 17:06    [21080317]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
softwarer
Попробуй, пока он работает, нажать, скажем, крестик в правом верхнем углу.
Ничего не произошло, и по крайней мере от Крестика я буду избавляться вообще!
Ну нельзя закрывать окно посредине открытого цикла!
Но это уже мелочи и совсем другая история...
3 янв 18, 17:15    [21080324]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
Ну нельзя закрывать окно посредине открытого цикла!
Даже если пользователь передумал ждать окончания твоего цикла?
3 янв 18, 17:19    [21080329]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Жаль только электроэнергии за нагрузку процессора в 100% и тормозов компьютера из-за этого.

Тормозов не наблюдается, а скачек нагрузки на CPU - c 25 до 50%. Это много?
Можно если захочется - таймером ворон на ветках посчитать!..)))
3 янв 18, 17:26    [21080338]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Даже если пользователь передумал ждать окончания твоего цикла?
Выход из процедуры будет возможен только по кнопке Выход, с корректными действиями.
А сам расчет (в Тестовом варианте - это счет от 0 до 500 и от 501 до 1000 и т.д.) в Реальном цикле выполняется достаточно быстро, так что юзер и не успеет мышкой на Крестик навести (Если он его еще сумеет найти на форме)!..)
3 янв 18, 17:32    [21080343]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
а скачек нагрузки на CPU - c 25 до 50%. Это много?

Значит у тебя 4 процессора (ядра). На одном уже "работала" подобная "программа", а эта запустилась на другом.
А если бы было одно ядро - нагрузка была бы 100.
Но не отчаивайся, и на многоядерных компьютерах, все программы, GUI-поток которых работал на том процессоре, который ты отправил в кому, будут тормозить.
Много это или не много - пользователям твоей программы решать.
3 янв 18, 17:34    [21080345]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock
Значит у тебя 4 процессора (ядра). На одном уже "работала" подобная "программа", а эта запустилась на другом.
А если бы было одно ядро - нагрузка была бы 100.
Но не отчаивайся, и на многоядерных компьютерах, все программы, GUI-поток которых работал на том процессоре, который ты отправил в кому, будут тормозить.
Много это или не много - пользователям твоей программы решать.
Да, верно, у меня 4 ядра!..)
С Одним ядром - это Pentium-1 что ли? Так мой уже такой давно на свалке!..))
А программа реальная - для узконаправленного круга пользователей пишется - для себя, ну максимум еще может для 2-х других друзей!

Ну а будут тормоза - можно и твоим Потоковым вариантом воспользоваться! - Он судя по индикатору - вообще не грузит процессор!..)
Надеюсь проблем, обращения из Потоковой процедуры к другим функциям и процедурам, не должно быть?!
3 янв 18, 17:59    [21080363]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
С Одним ядром - это Pentium-1 что ли?

В твоём случае, если б у тебя было 2 ядра, оба стали б заняты (т.к. 1-е уже кто-то занял).
Не, если не жалко электроэнергии и нервов, плевать на прокляться благодарных пользователей - я ж не против.

Bellic
Потоковой процедуры к другим функциям и процедурам, не должно быть

Функциям и процедуры, как и память, не принадлежат какому-то потоку. Их можно использовать из любого.
Только поток кода будет хоть и одинаков, если вызывать одну функцию в разных потоках, но их будет несколько, а вот память - одна на всех.
3 янв 18, 18:08    [21080381]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45049

Bellic
скачек нагрузки на CPU - c 25 до 50%. Это много?

Это полный П. У правильно написанной программы в покое должно быть нулевое потребление ЦПУ.

Posted via ActualForum NNTP Server 1.5

3 янв 18, 18:13    [21080388]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
YuRock, Кстати - добавил Sleep(1); в ЭТОТ КОД, и процент загруженности вообще упал, проверь:
while FRes = 0 do
begin
  Sleep(1);
  Application.ProcessMessages;
end;

- Без Sleep(1) -- 25-27% в ожидании нажатия клавиш;
- Со Sleep(1) -- загрузка в ожидании практически не увеличилась (1-5%)!
3 янв 18, 18:18    [21080396]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Продолжаем дальше фигнёй страдать??)) А вот воспользовались бы таймером, даже в потоке. То не пришлось бы заниматься такими оптимизациями)))
3 янв 18, 18:25    [21080401]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Тем более, applicationevents сообщит о нажатии клавиши. И вообще не надо никаких собственных крутых for-ов
3 янв 18, 18:26    [21080405]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
rgreat
Member

Откуда:
Сообщений: 4160
Bellic,

А теперь попробуй закрыть программу крестиком.
3 янв 18, 18:30    [21080411]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
YuRock, Кстати - добавил Sleep(1); в ЭТОТ КОД, и процент загруженности вообще упал, проверь:
while FRes = 0 do
begin
  Sleep(1);
  Application.ProcessMessages;
end;


- Без Sleep(1) -- 25-27% в ожидании нажатия клавиш;
- Со Sleep(1) -- загрузка в ожидании практически не увеличилась (1-5%)!

Не хочу я пробовать
Это мрак. Что со слипом, что без.
3 янв 18, 18:41    [21080433]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
rgreat
Bellic, А теперь попробуй закрыть программу крестиком.
rgreat, Вы похоже Тему вообще не читаете!?
ВОТ ТУТ я уже ответил на этот вопрос!
Ну нету у меня на Реальной форме КРЕСТИКА!!! На Тестовой форме он конечно имеется, но я не буду туда нажимать!
Я форму создавал сразу без крестиков, значков сворачивания и минимизаций! Что бы потом вопросов не было!..)
3 янв 18, 18:44    [21080440]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Беллик, сделай нормально, правда :) Тебе же самому будет лучше и проще потом. Не надо потоков бояться, всё там с ними просто, если один раз разобраться. ProcessMessages - это, как правило, костыль, хоть со слипом, хоть без. Рано или поздно он гарантированно вылезет боком. Причём в таком месте, что вообще никак не связано напрямую с кодом. И вот тогда всю голову сломаешь, почему глючит.
3 янв 18, 18:49    [21080456]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Няшик
Продолжаем дальше фигнёй страдать??)) А вот воспользовались бы таймером, даже в потоке. То не пришлось бы заниматься такими оптимизациями)))
А кто Вам мешает написать свой вариант на основе моего Тестового и приложить к сообщению полный рабочий проект(без ошибок ток)?
Тем более, applicationevents сообщит о нажатии клавиши. И вообще не надо никаких собственных крутых for-ов

Няшик, мне на пиво братишка позвал, к сожалению вернусь только завтра, но я хотел бы Заценить и Ваш вариант с Таймером и Эвентсами!
3 янв 18, 18:53    [21080459]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
rgreat
Member

Откуда:
Сообщений: 4160
Bellic,

Хех, присоединюсь к остальным: Страдай фигней, на здоровье.
3 янв 18, 18:57    [21080469]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
makhaon
Беллик, сделай нормально, правда :) Тебе же самому будет лучше и проще потом. Не надо потоков бояться, всё там с ними просто, если один раз разобраться. ProcessMessages - это, как правило, костыль, хоть со слипом, хоть без. Рано или поздно он гарантированно вылезет боком. Причём в таком месте, что вообще никак не связано напрямую с кодом. И вот тогда всю голову сломаешь, почему глючит.

Да я собственно с Потоков и начинал тему, до этого просто никогда не работал с ними!
Но по ходу оказалось, что можно и без них обойтись, и код очень коротким получался ведь!?

А что касается ProcessMessages, то я им и в других затяжных процедурах пользуюсь, чтоб избавиться от "Программа не отвечает"(или как там?) в шапке форм! А как по другому этого избежать?
Вот недавно сравнительно узнал, что можно ProgressBar.Refresh делать!
3 янв 18, 19:01    [21080474]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Док
Member

Откуда: Казань
Сообщений: 5611
дивлюсь я вам, мужики. Вместо того, чтобы доедать оливье и в телик пялиться, вы домашку школьнику, пересевшего с бейсика на паскаль, делаете. Да и еще с ним аргументированно спорить пытаетесь
3 янв 18, 19:11    [21080488]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
makhaon
Member

Откуда: A galaxy far far away
Сообщений: 2571
Док,

Не знаю, как кто, я уже оливье с шубой объелся Хватит, надо калории немного потратить ) Пациент не совсем упоротый, шансы есть.
3 янв 18, 19:14    [21080493]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
Bellic,

У меня всё без ошибок работает. Ошибки делаешь ты...

Это задача вообще на 10 - 20 минут в реализации.

Может бы начал с чего нибудь полегче ????


Няшик
Циклы к слову вообще не нужны, уже есть ApplicationEvents

Можно и так сделать ведь
+
procedure TForm1.ApplicationEvents1Message(var Msg: tagMSG;
  var Handled: Boolean);
begin
  if Msg.message = 513 then
  begin
    if not SButtonEnebled then
    begin
      if Msg.hwnd = SButton.Handle then
        SButtonEnebled := true
      else
        Memo1.Lines.Add('Кряя. Надо нажать на SButton');
      exit;
    end;

    if Msg.hwnd = Button1.Handle then
      Memo1.Lines.Add('Нажата кн."Продолжить"')
    else if Msg.hwnd = Button2.Handle then
      Memo1.Lines.Add('Нажата кн."Пропустить"')
    else if Msg.hwnd = Button3.Handle then
      Memo1.Lines.Add('Счет Остановлен!')
    else
      exit;

    SButtonEnebled := false;
  end
  else if Msg.message = 257 then
  begin
    Memo1.Lines.Add('Нажата кнопка: ' + chr(Msg.wParam));
  end;
end;
3 янв 18, 19:28    [21080514]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
makhaon,

Я уже поправился на 8 кг... Тяжело ходить даже стало xD
3 янв 18, 19:30    [21080519]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
избавиться от "Программа не отвечает"(или как там?) в шапке форм! А как по другому этого избежать?

Делать тяжелую работу в другом потоке.

Bellic
Вот недавно сравнительно узнал, что можно ProgressBar.Refresh делать!

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

Bellic
код очень коротким получался ведь!?

Более того, ты вызовом принудительной отрисовки (ProgressBar.Refresh и подобного) замедляешь работу основного своего алгоритма, который ты называешь "циклом".
3 янв 18, 19:37    [21080540]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Bellic
код очень коротким получался ведь!?

Да, и еще. Мой код (с потоком) на 5 с половиной строк больше твоего потому, что я предусмотрел для пользователя возможность в любой момент корректно и сразу закрыть программу.
Если уважение к пользователям не нужно - можно убрать оттуда некоторые проверки, кое-где Wait заменить на Sleep, работать по FreeOnTerminate=True, и еще много чего.

Уверяю тебя, что код с потоком получится меньше, чем у тебя (хотя бы потому, что нет goto в основном алгоритме). И будет висеть при нажатии на крестик, пока не закончится "цикл", как ты любишь.
3 янв 18, 19:46    [21080558]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Freedoom
Guest
YuRock
Bellic
Freedoom, очень интересно получилось! Класс!
(Нет явного цикла ожидания, доп.потока и TAG использован по совету парней!)

Жаль только электроэнергии за нагрузку процессора в 100% и тормозов компьютера из-за этого.

Если речь идёт об экономии электроэнергии на время обдумывания выбора варианта ответа пользователем, то никто не мешает глянуть на реализацию ShowModal в первоисточниках и переделать цикл
repeat
  Application.HandleMessage;
until (FRes <> 0) or Application.Terminate;
3 янв 18, 21:21    [21080673]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Freedoom
переделать цикл
repeat
  Application.HandleMessage;
until (FRes <> 0) or Application.Terminate;
Это уже лучше, хотя и все равно мрак.
И это не первоисточники, а такие же костыли и грабли.
3 янв 18, 22:21    [21080772]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Freedoom
Guest
YuRock, см реализацию ShowModal в vcl.forms.pas
4 янв 18, 01:37    [21081088]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Freedoom
YuRock, см реализацию ShowModal в vcl.forms.pas
Я её смотрел уже раньше. Костыли и грабли.
Такой подход иногда допустим, когда действительно надо быстро вставить костыль в готовую рабочую систему, и другого выхода нет, кроме как всё переделывать, что может быть не выгодно.
Но заложить такое в основу библиотеки... Я когда первый раз наступил на это и увидел в чем проблема... Такого я от Борланда не ожидал.
4 янв 18, 02:26    [21081126]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Няшик
Member

Откуда: Екатеринбург
Сообщений: 885
YuRock
Такого я от Борланда не ожидал.


По моему они уже скатились, и сейчас выпускают что бы была активность для продаж
4 янв 18, 09:47    [21081236]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Vizit0r
Member

Откуда:
Сообщений: 559
Няшик, ты будешь удивлен, но Борланда уже почти 10 лет как не существует.
4 янв 18, 09:50    [21081237]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3415
Няшик
YuRock
Такого я от Борланда не ожидал.


По моему они уже скатились, и сейчас выпускают что бы была активность для продаж
Код ShowModal не менялся больше 20 лет.
4 янв 18, 11:44    [21081361]     Ответить | Цитировать Сообщить модератору
 Re: Обработка нажатия трех кнопок в параллельном потоке  [new]
Bellic
Member

Откуда: Ростов-на-Дону
Сообщений: 231
Привет Сиквелцам!
Не хочется никого отвлекать пустыми разговорами - для себя оценил вариант YuRock-ка, поэтому буду внедрять Поток в свою прогу!
Единственное - хотелось бы увидеть полностью законченный вариант от Няшик-ка на Events!
Кнопки у него на форме имеются, а счет - отсутствует!
Няшик, допиши плизз...))

P.S. Прикрепляю полностью вариант проекта Няшик-ка для XE3 c двумя его реализациями - с массивами и без них, но в обоих случаях отсутствует цикл счета с выводом в MLabel: TLabel;

К сообщению приложен файл (-= EVENTS-НЯШИК =-.rar - 91Kb) cкачать
4 янв 18, 20:06    [21082244]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2 3 4 5      [все]
Все форумы / Delphi Ответить