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

Откуда:
Сообщений: 1963
А вот таким образом правильно будет по завершении работы потока получить из него результат выполнения (id первой обновленной записи)?
ChThread := TChangeOwnerThread.Create(coChange, placement_cargo_card_id);
  try
    ChThread.Start;
  finally
    if ChThread.ret_cargo_card_id <> 0 then
      begin
        ChangeQueryCargo; // обновляет основную сетку
        placement_cargo_card_id := ChThread.ret_cargo_card_id; // позиционирует курсор на запись в сетке
      end;
    ChThread.Free;
  end;

Или такой код приведет к открытию потока и немедленному его уничтожению?
Если что, код самого Create примерно такой:
constructor TChangeOwnerThread.Create(AMode: TcoMode; const ACargoCardId: Integer);
begin
  FMode := AMode;
  Fcargo_card_id := ACargoCardId;

  FfmProgress := TfmChangeOwnerProgress.Create(nil);
  FfmProgress.ShowModal;

  OnTerminate := TerminateHandler;
  inherited Create(true);
  FreeOnTerminate := false;
end;
28 сен 18, 15:51    [21689230]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
В общем нужно после отрабатывания всех SQL-запросов, которые засунуты в поток (после завершения работы потока), обновить основную сетку с данными и позиционировать курсор (Locate) на ту запись, id которой будет храниться внутри потока. Как это грамотно сделать?
28 сен 18, 15:55    [21689239]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
wadman
Member

Откуда: Санкт-Петербург
Сообщений: 24625
svnvlad
Как это грамотно сделать?

Посмотри туда https://github.com/wadman/wthread
28 сен 18, 15:57    [21689244]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
svnvlad
zinpub
Ну и добавь invalidate и sleep, раз в N-дцать записей

Нет, все бесполезно, и sleep, и Repaint, и Application.ProcessMessages делал, не помогает. Лучше напишу поток.

Куда тебе еще поток, ты прогрессбаром разобраться не можешь...
28 сен 18, 17:05    [21689342]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
QT
Guest
Изначально вопрос был про ProgressBar.
И вот этот пример кода показывает, что ProgressBar нормально отображается и без потоков и без каких-либо ProcessMessages() / Repaint() / Update() / Invalidate().
Надо смотреть подробнее. Сделайте вывод в логи.
28 сен 18, 17:12    [21689351]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
schi
YuRock
пропущено...
Перед Update еще Invalidate надо, я забыл, или сразу Repaint - он и то и то вызовет.


Нафига ? SetPosition у ProgressBar и так объявляет недействительным нужные части окна.
Если так (что логично и скорей всего, просто нет щас уозможности исходники посмотреть) - тогда не надо. Значит, ошибка в логике, и тогда ничего не поможет, кроме исправления её.
28 сен 18, 22:32    [21689601]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
svnvlad
То ли сообщения не доходят, то ли не считает нужным немедленно на них реагировать.
Нет, всё всегда работает в соответствие с жокументацией по винапи. За исключением редких багов, которые в основном давно вылизаны и пофикшены.
28 сен 18, 22:35    [21689604]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
zinpub
Ну и добавь invalidate и sleep, раз в N-дцать записей
слип бесполезен, а инвалидэйта мало - нужен апдейт. Так говорит документация, а жизнь показывает, что она не врет в данном случае.
Так что тыкать пальцем в небо - просто потеря времени.
28 сен 18, 22:37    [21689608]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
zinpub
Проблема в чём то ином, ProcessMessages для прогрессбара вполне достаточно, хотя и кривовато
Не достаточно, винда пошлет WM_PAINT только после того, как очередь освободится, а надо сразу.
28 сен 18, 22:38    [21689609]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
YuRock
zinpub
Проблема в чём то ином, ProcessMessages для прогрессбара вполне достаточно, хотя и кривовато
Не достаточно, винда пошлет WM_PAINT только после того, как очередь освободится, а надо сразу.
Даже точнее так: после ProcessMessages винда пошлет WM_PAINT через PostMessage (добавит в очередь), но обработка этого сообщения не начнется сразу, т.к. пойдет выполнение дальнейшего кода программы, в итоге - окно с прогрессбаром не перерисуется (когда надо).
28 сен 18, 22:43    [21689612]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
YuRock
YuRock
пропущено...
Не достаточно, винда пошлет WM_PAINT только после того, как очередь освободится, а надо сразу.
Даже точнее так: после ProcessMessages винда пошлет WM_PAINT через PostMessage (добавит в очередь), но обработка этого сообщения не начнется сразу, т.к. пойдет выполнение дальнейшего кода программы, в итоге - окно с прогрессбаром не перерисуется (когда надо).

Все правильно.

Котовасия
Куда тебе еще поток, ты прогрессбаром разобраться не можешь...

Сами попробуйте обновлять прогрессбар в цикле MySQL. Сто раз уже такое встречал, что замораживается до конца цикла, просто руки не доходили основательно решить вопрос.
28 сен 18, 22:57    [21689619]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Василий 2
В данном случае поток это оверхед. Код нормальный, почему не работает как надо - непонятно.
Пример ведет себя как надо
type
  TForm2 = class(TForm)
    ProgressBar1: TProgressBar;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  while ProgressBar1.Position < ProgressBar1.Max do
  begin
    ProgressBar1.StepIt;
    sleep(100);
  end;
end;


Попробуй логировать ChangedCount при вызовах


Вот вывод с "логированием" - логирование осуществляется вызовом функции ShowMessage. Как и ожидалось, все отображается. И не нужны даже Update с ProcessMessages.
// 2. Перенести все карточки в новый подтип груза по договору
    q.From('cargo_card', 'cc');
    q.Select('cc.id');
    q.Where('object_type= ?', 'placement');
    q.AndWhere('get_weight_brutto_remains(cc.id) > 0', '');
    q.AndWhere('cc.contract_cargo_sub_id=?', AOldContractCargoSubId);
    q.Open;
    while not q.Q.Eof do
      begin
        if DoChangeOwnerCargoCard(q.Q.FieldByName('id').AsInteger, ANewContractCargoSubId) <> 0 then
          begin
            inc(ChangedCount);
            if Assigned(fP) then
              fP.Position3 := ChangedCount;
            ShowMessage(IntToStr(ChangedCount));
          end;
        q.Q.Next;
      end;


К сообщению приложен файл. Размер - 18Kb
28 сен 18, 23:09    [21689625]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Вторая

К сообщению приложен файл. Размер - 21Kb
28 сен 18, 23:09    [21689627]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Третья

К сообщению приложен файл. Размер - 22Kb
28 сен 18, 23:10    [21689628]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Результат

К сообщению приложен файл. Размер - 26Kb
28 сен 18, 23:10    [21689629]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
И это немудрено, во время висения диалоговых ShowMesage-й у программы достаточно времени, чтобы обработать все сообщения.
28 сен 18, 23:12    [21689631]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
svnvlad
...
Котовасия
Куда тебе еще поток, ты прогрессбаром разобраться не можешь...

Сами попробуйте обновлять прогрессбар в цикле MySQL. Сто раз уже такое встречал, что замораживается до конца цикла, просто руки не доходили основательно решить вопрос.


Вот тебе код, повесь его "на кнопку", попробуй - заработает ли.
var
  f: TForm;
  i: Integer;
  pb: TProgressBar;
begin
  f := TForm.Create(nil);
  f.SetBounds(0, 0, 300, 70);
  f.Position := poScreenCenter;
  pb := TProgressBar.Create(f);
  pb.Align := alClient;
  pb.Parent := f;
  pb.Min := 1;
  pb.Max := 100;
  pb.Step := 1;
  f.Show();
  for i := pb.Min to pb.Max do begin
    pb.StepIt;
    sleep (100);
  end;
  f.Free;
end;

Если заработает - замени sleep(100) на свою работу с mySQL
28 сен 18, 23:13    [21689633]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
krapotkin
Member

Откуда: Екатеринбург
Сообщений: 637
тут вроде в правилах нет ограничений на ссылки
я писал статью, где ваш случай подробно описан
29 сен 18, 08:38    [21689734]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3631
Котовасия
svnvlad
...
пропущено...

Сами попробуйте обновлять прогрессбар в цикле MySQL. Сто раз уже такое встречал, что замораживается до конца цикла, просто руки не доходили основательно решить вопрос.


Вот тебе код, повесь его "на кнопку", попробуй - заработает ли.
var
  f: TForm;
  i: Integer;
  pb: TProgressBar;
begin
  f := TForm.Create(nil);
  f.SetBounds(0, 0, 300, 70);
  f.Position := poScreenCenter;
  pb := TProgressBar.Create(f);
  pb.Align := alClient;
  pb.Parent := f;
  pb.Min := 1;
  pb.Max := 100;
  pb.Step := 1;
  f.Show();
  for i := pb.Min to pb.Max do begin
    pb.StepIt;
    sleep (100);
  end;
  f.Free;
end;


Если заработает - замени sleep(100) на свою работу с mySQL
Вряд ли заработает. Тут та же проблема, что и у ТС, идентичная.
29 сен 18, 09:19    [21689739]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
andreymx
Member

Откуда: Запорожье
Сообщений: 49183
svnvlad
function TfmCargoOutgoing.DoChangeOwnerContractCargoSub(AOldContractCargoSubId,
  ANewContractCargoSubId: integer): integer;
var
  CardCount: integer;
  ChangedCount: integer; // кол-во измененных карточек
begin
  ChangedCount := 0;

...
    // 1. Определить количество карточек для переноса
    ...
    if Assigned(fP) then
      fP.Max3 := CardCount; // инициализация общего количества для прогресс-бара
    ....
    // 2. Перенести все карточки в новый подтип груза по договору    
    while not q.Q.Eof do
      begin
        if DoChangeOwnerCargoCard(q.Q.FieldByName('id').AsInteger, ANewContractCargoSubId) <> 0 then
          begin
            inc(ChangedCount);

            if Assigned(fP) then
              fP.Position3 := ChangedCount; // обновление позиции прогресс-бара

          end;
        q.Q.Next;
      end;

    Result := ChangedCount;
end;
выбросить код slow-by-slow и написать sp-процедуру предлагали?
29 сен 18, 11:05    [21689767]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
schi
Member

Откуда: Москва
Сообщений: 2601
YuRock
YuRock
пропущено...
Не достаточно, винда пошлет WM_PAINT только после того, как очередь освободится, а надо сразу.
Даже точнее так: после ProcessMessages винда пошлет WM_PAINT через PostMessage (добавит в очередь), но обработка этого сообщения не начнется сразу, т.к. пойдет выполнение дальнейшего кода программы, в итоге - окно с прогрессбаром не перерисуется (когда надо).


https://docs.microsoft.com/en-us/windows/desktop/controls/create-progress-bar-controls

Нет никаких Invalidate, Update и прочих действий. Где-то я читал (не найду сейчас), что ProgressBar отличается от остальных контролов тем, что при установке позиции он сам вызывает UpdateWindow
29 сен 18, 11:39    [21689784]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
Котовасия
Member

Откуда:
Сообщений: 1187
YuRock
Котовасия
пропущено...


Вот тебе код, повесь его "на кнопку", попробуй - заработает ли.
var
  f: TForm;
  i: Integer;
  pb: TProgressBar;
begin
  f := TForm.Create(nil);
  f.SetBounds(0, 0, 300, 70);
  f.Position := poScreenCenter;
  pb := TProgressBar.Create(f);
  pb.Align := alClient;
  pb.Parent := f;
  pb.Min := 1;
  pb.Max := 100;
  pb.Step := 1;
  f.Show();
  for i := pb.Min to pb.Max do begin
    pb.StepIt;
    sleep (100);
  end;
  f.Free;
end;



Если заработает - замени sleep(100) на свою работу с mySQL
Вряд ли заработает. Тут та же проблема, что и у ТС, идентичная.

Это рабочий код.
29 сен 18, 12:21    [21689811]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Котовасия
YuRock
пропущено...
Вряд ли заработает. Тут та же проблема, что и у ТС, идентичная.

Это рабочий код.

Шаман однако.
На кнопке код работал. Попробовал встроить в SQL-цикл. Тоже показал прогресс. Затем закомментировал этот код и оставил свой код как было, убрал даже ProcessMessages и Repaint где они были. Все заработало нормально. В коде НИЧЕГО не менял. Но вчера он не работал, а сегодня работает. Одно замечание - вчера работало все медленно, сегодня быстро, т.е. связь с сервером лучше. Вчера обработка 3 запросов занимала где-то 3 секунды, сегодня доли секунды. Может быть с этим связано?
29 сен 18, 23:37    [21690142]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Даже так - прежде, чем начал тестировать этот код, заметил, что мое окно с прогресс барами работает нормально.
29 сен 18, 23:38    [21690144]     Ответить | Цитировать Сообщить модератору
 Re: Как в процессе исполнения ряда SQL-запросов отображать прогресс-бар? (thread?)  [new]
svnvlad
Member

Откуда:
Сообщений: 1963
Вчера день потратил на написание класса Thread-а, а сегодня оказалось, что работает без него. Дельфи издевается?
29 сен 18, 23:40    [21690147]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: Ctrl  назад   1 [2] 3 4 5   вперед  Ctrl      все
Все форумы / Delphi Ответить