Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Заполнение несколькоких списков в отдельных потоках / 25 сообщений из 48, страница 1 из 2
28.05.2020, 20:37
    #39963613
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
Из головы вылетело...
Не могу вспомнить, как называется функционал, когда туда передаешь свою процедуру и она выполняется там в отдельном потоке?
...
Рейтинг: 0 / 0
28.05.2020, 20:51
    #39963621
Gluck99
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
...
Рейтинг: 0 / 0
28.05.2020, 20:53
    #39963622
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
По-моему, я о чем-то другом когда-то читал.
Вроде похоже, а вроде нет.
...
Рейтинг: 0 / 0
28.05.2020, 20:59
    #39963625
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
TTask
...
Рейтинг: 0 / 0
28.05.2020, 22:41
    #39963691
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
Вопрос в том, а можно ли с помощью TTask заполнять визуальные компоненты?
...
Рейтинг: 0 / 0
28.05.2020, 22:45
    #39963696
wadman
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
X11
Вопрос в том, а можно ли с помощью TTask заполнять визуальные компоненты?

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

http://www.proghouse.ru/programming/36-delphi-xe7-ppl?hitcount=0
...
Рейтинг: 0 / 0
28.05.2020, 23:08
    #39963718
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
--
...
Рейтинг: 0 / 0
28.05.2020, 23:26
    #39963731
X11
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
28.05.2020, 23:37
    #39963734
DmSer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
А для чего тут доп.поток понадобился?
...
Рейтинг: 0 / 0
28.05.2020, 23:39
    #39963735
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
DmSer, ты имеешь ввиду, для чего понадобился TThread.Synchronize?
...
Рейтинг: 0 / 0
28.05.2020, 23:40
    #39963736
DmSer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
И он в том числе.
...
Рейтинг: 0 / 0
28.05.2020, 23:46
    #39963739
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
Я же написал. Или получилось непонятно?
На форме есть, например, 10 списков.
Если вызывать процедуры заполнения по очереди, то каждая следующая будет вызвана только после того, как закончиться предыдущая. Но зачем же ждать? Если можно все 10 списков заполнить почти одновременно...
...
Рейтинг: 0 / 0
28.05.2020, 23:53
    #39963743
DmSer
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
Стало сильно быстрее?
...
Рейтинг: 0 / 0
28.05.2020, 23:59
    #39963745
X11
X11
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Заполнение несколькоких списков в отдельных потоках
нет
но это данных в таблицах мало
но я надеюсь, что на медленных ПК и с бОльшим количеством данных будет чуть ощутиммее

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

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

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

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

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

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

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

Всё, кроме передачи списка, который можно собрать в отдельный TStringList.
В чекбоксе потом достаточно сделать Items.Assign.
...
Рейтинг: 0 / 0
29.05.2020, 11:17
    #39963942
X11
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
29.05.2020, 11:36
    #39963951
X11
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
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Заполнение несколькоких списков в отдельных потоках / 25 сообщений из 48, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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