powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Заполнение несколькоких списков в отдельных потоках
25 сообщений из 48, страница 1 из 2
Заполнение несколькоких списков в отдельных потоках
    #39963613
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Из головы вылетело...
Не могу вспомнить, как называется функционал, когда туда передаешь свою процедуру и она выполняется там в отдельном потоке?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963621
Gluck99
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963622
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По-моему, я о чем-то другом когда-то читал.
Вроде похоже, а вроде нет.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963625
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TTask
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963691
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос в том, а можно ли с помощью TTask заполнять визуальные компоненты?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963696
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
Вопрос в том, а можно ли с помощью TTask заполнять визуальные компоненты?

Через synchronize.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963717
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
т.е. внутрь анонимной процедуры TTask нужно вставить ещё одну анонимную процедуру с TThread.Synchronize

http://www.proghouse.ru/programming/36-delphi-xe7-ppl?hitcount=0
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963718
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
--
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963731
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Получился вот такой монстр


procedure FillCxCheckListBox
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
procedure FillCxCheckListBox(clb: TcxCheckListBox; st: TSuperType; const TableName, JoinField, sCond: string);
Var
  task: ITask;

begin
  if not assigned(clb) then exit;

  task := TTask.Create(procedure ()
    const sql = 'SELECT DISTINCT ' +
                '    I.ID,       ' +
                '    I.NAME      ' +
                'FROM            ' +
                '    @@TABLE@ I  ' +
                'INNER JOIN @@MAIN_TABLE@ T ON T.@@JOIN_FIELD@ = I.ID';

    Var
      lc: TdxLayoutControl;
      li: TdxLayoutItem;
      task: ITask;
      q: TpFIBQuery;
      tr: TpFIBTransaction;

  begin

    TThread.Synchronize(nil, procedure()
    begin
        q := DM.CreateFibQuery;
        tr := TpFIBTransaction.Create(q);
        tr.DefaultDatabase := DM.fibDB;
        q.Transaction := tr;
        q.SQL.Text := sql;

    //    q.close;
    //    q.Conditions.CancelApply;
    //    q.Conditions.Clear;

        lc := TdxLayoutControl(clb.Parent);
        li := lc.FindItem(clb.Handle);
        if not LayoutItemVisible(li) then exit;


        //если список уже заполнен, то нет смысла заполнять повторно
        if  clb.Items.Count > 0 then exit;

        clb.Items.BeginUpdate;
        try
          clb.EditValueFormat := cvfIndices;

          if sCond <> '' then
          begin
            q.Conditions.AddCondition('cond1', sCond, true);
            q.Conditions.Apply;
          end;

          // MAIN_TABLE - только если были ОН, у которых использовались те или иные значения справочника
          q.ParamByName('MAIN_TABLE').Value := GetTableNameBySupertype(st);// APART, ARENDA
          q.ParamByName('TABLE').Value      := TableName;
          q.ParamByName('JOIN_FIELD').Value := JoinField;
          q.ExecQuery;


          While not q.Eof do
          begin
            with TcxCheckListBoxItem.Create(clb.Items) do
            begin
              Tag  := q.Fields[0].AsInteger;// id
              Text := q.Fields[1].AsString;// name
            end;//with

            q.Next;
          end;//while
        finally
          clb.Items.EndUpdate;
          q.Close;
          FreeAndNil(q);
        end;

    end);// TThread.Synchronize(

  end);// TTask
  task.Start;

end;

...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963734
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А для чего тут доп.поток понадобился?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963735
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSer, ты имеешь ввиду, для чего понадобился TThread.Synchronize?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963736
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
И он в том числе.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963739
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я же написал. Или получилось непонятно?
На форме есть, например, 10 списков.
Если вызывать процедуры заполнения по очереди, то каждая следующая будет вызвана только после того, как закончиться предыдущая. Но зачем же ждать? Если можно все 10 списков заполнить почти одновременно...
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963743
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Стало сильно быстрее?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963745
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
нет
но это данных в таблицах мало
но я надеюсь, что на медленных ПК и с бОльшим количеством данных будет чуть ощутиммее

тут вот в чем прикол, оно ж как получается: то в заполнении списков треть секунды выиграл, то в загрузке настроек и параметров треть секунды выиграл, в итоге даже если на 1 секунду быстрее, уже приятнее.
Если пользователь форму открывает не 5 секунд, а 1-2, то уже классс..

Вот эта форма когда-то открывалась 5-7 секунд, я давно об этом где-то здесь писал, ещё и с Рустамом, помню, на этот счет общались на форуме, а теперь - меньше 2 секунд.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963746
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11,

Вызывая TThread.Synchronize для всего тормозящего кода целиком ты добьешься только того что все потоки будут выполнятся по очереди.

Короче фигню ты написал.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963748
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Почему по очереди?
Ведь заполняют разные визуальные компоненты.
Плюс отрисовки нет (я так предполагаю), это выполняется в событии FormShow и на закрытой вкладке PageControl`а.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963751
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11,

Все что находится в Synchronize выполняется в главном потоке. По очереди.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963754
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Т.е. физически никак не заполнить списки моментально одновременно?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963761
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
Т.е. физически никак не заполнить списки моментально одновременно?

Можно сделать списки виртуальными, заполнять хранилища данных в потоках, а потом через Synchronize передавать заполненные списки в основное приложение.
И да, подключение к БД в каждом потоке должно быть своё.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963764
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvp,

Да ему достаточно только запрос в БД за пределы Synchronize вынести и уже все ускориться в разы.
И никакие временные списки не нужны.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963906
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Чтобы q.ExecQuery был вне TThread.Synchronize?
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963921
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X11
Чтобы q.ExecQuery был вне TThread.Synchronize?

Всё, кроме передачи списка, который можно собрать в отдельный TStringList.
В чекбоксе потом достаточно сделать Items.Assign.
...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963942
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если перенести строки

TThread.Synchronize(nil, procedure()
begin
и поставить после q.ExecQuery, то вываливает несколько AV и ошибок, в том числе и при закрытии формы


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
procedure FillCxCheckListBox(clb: TcxCheckListBox; st: TSuperType; const TableName, JoinField, sCond: string);
Var
  task: ITask;

begin
  if not assigned(clb) then exit;

  task := TTask.Create(procedure ()
    const sql = 'SELECT DISTINCT ' +
                '    I.ID,       ' +
                '    I.NAME      ' +
                'FROM            ' +
                '    @@TABLE@ I  ' +
                'INNER JOIN @@MAIN_TABLE@ T ON T.@@JOIN_FIELD@ = I.ID';

    Var
      lc: TdxLayoutControl;
      li: TdxLayoutItem;
      q: TpFIBQuery;
      tr: TpFIBTransaction;

  begin


        q := DM.CreateFibQuery;
        tr := TpFIBTransaction.Create(q);
        tr.DefaultDatabase := DM.fibDB;
        q.Transaction := tr;
        q.SQL.Text := sql;

    //    q.close;
    //    q.Conditions.CancelApply;
    //    q.Conditions.Clear;

        lc := TdxLayoutControl(clb.Parent);
        li := lc.FindItem(clb.Handle);
        if not LayoutItemVisible(li) then exit;


        //если список уже заполнен, то нет смысла заполнять повторно
        if  clb.Items.Count > 0 then exit;

        clb.Items.BeginUpdate;
        //try
          clb.EditValueFormat := cvfIndices;

          if sCond <> '' then
          begin
            q.Conditions.AddCondition('cond1', sCond, true);
            q.Conditions.Apply;
          end;

          // MAIN_TABLE - только если были ОН, у которых использовались те или иные значения справочника
          q.ParamByName('MAIN_TABLE').Value := GetTableNameBySupertype(st);// APART, ARENDA
          q.ParamByName('TABLE').Value      := TableName;
          q.ParamByName('JOIN_FIELD').Value := JoinField;
          q.ExecQuery;


    TThread.Synchronize(nil, procedure()
    begin
       try

          While not q.Eof do
          begin
            with TcxCheckListBoxItem.Create(clb.Items) do
            begin
              Tag  := q.Fields[0].AsInteger;// id
              Text := q.Fields[1].AsString;// name
            end;//with

            q.Next;
          end;//while
        finally
          clb.Items.EndUpdate;
          q.Close;
          FreeAndNil(q);
        end;

    end);// TThread.Synchronize(

  end);// TTask
  task.Start;

end;

...
Рейтинг: 0 / 0
Заполнение несколькоких списков в отдельных потоках
    #39963951
Фотография X11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, почитал тему 21139822 , переделал так
пока хотя бы без ошибок

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
procedure FillCxCheckListBox(clb: TcxCheckListBox; st: TSuperType; const TableName, JoinField, sCond: string);
//Var
//  task: ITask;
    const sql = 'SELECT DISTINCT ' +
                '    I.ID,       ' +
                '    I.NAME      ' +
                'FROM            ' +
                '    @@TABLE@ I  ' +
                'INNER JOIN @@MAIN_TABLE@ T ON T.@@JOIN_FIELD@ = I.ID';

    Var
      lc: TdxLayoutControl;
      li: TdxLayoutItem;
      q: TpFIBQuery;
      tr: TpFIBTransaction;

begin
  if not assigned(clb) then exit;

//  TThread.Synchronize(TThread.CurrentThread, procedure ()
//    const sql = 'SELECT DISTINCT ' +
//                '    I.ID,       ' +
//                '    I.NAME      ' +
//                'FROM            ' +
//                '    @@TABLE@ I  ' +
//                'INNER JOIN @@MAIN_TABLE@ T ON T.@@JOIN_FIELD@ = I.ID';
//
//    Var
//      lc: TdxLayoutControl;
//      li: TdxLayoutItem;
//      q: TpFIBQuery;
//      tr: TpFIBTransaction;

//  begin


        q := DM.CreateFibQuery;
        tr := TpFIBTransaction.Create(q);
        tr.DefaultDatabase := DM.fibDB;
        q.Transaction := tr;
        q.SQL.Text := sql;

    //    q.close;
    //    q.Conditions.CancelApply;
    //    q.Conditions.Clear;

        lc := TdxLayoutControl(clb.Parent);
        li := lc.FindItem(clb.Handle);
        if not LayoutItemVisible(li) then exit;


        //если список уже заполнен, то нет смысла заполнять повторно
        if  clb.Items.Count > 0 then exit;

        clb.Items.BeginUpdate;
        //try
          clb.EditValueFormat := cvfIndices;

          if sCond <> '' then
          begin
            q.Conditions.AddCondition('cond1', sCond, true);
            q.Conditions.Apply;
          end;

          // MAIN_TABLE - только если были ОН, у которых использовались те или иные значения справочника
          q.ParamByName('MAIN_TABLE').Value := GetTableNameBySupertype(st);// APART, ARENDA
          q.ParamByName('TABLE').Value      := TableName;
          q.ParamByName('JOIN_FIELD').Value := JoinField;
          q.ExecQuery;


//    TThread.Synchronize(nil, procedure()
//    begin
  TThread.Synchronize(TThread.CurrentThread, procedure ()
  begin
       try

          While not q.Eof do
          begin
            with TcxCheckListBoxItem.Create(clb.Items) do
            begin
              Tag  := q.Fields[0].AsInteger;// id
              Text := q.Fields[1].AsString;// name
            end;//with

            q.Next;
          end;//while
        finally
          clb.Items.EndUpdate;
          q.Close;
          FreeAndNil(q);
        end;

//    end);// TThread.Synchronize(

  end);// TTask
  //task.Start;

end;

...
Рейтинг: 0 / 0
25 сообщений из 48, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Заполнение несколькоких списков в отдельных потоках
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]