Форум программистов, компьютерный форум, киберфорум
Delphi
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
1

Поток - Thread, как с ним работать

13.07.2012, 18:54. Показов 1425. Ответов 14
Метки нет (Все метки)

Здравствуйте, Нужно создать (отдельный модуль) поток(с отображением Progressbar'ом) с одной функцией проверкой на существование файлов в папке(Структура папок: корневая папка -LIT, в ней расположены другие папки(с файлами) и файлы) - названия папок и файлов неизвестно, т.е. - технически они будут известны после запуска программы (функция сканирования добавит все папки с файлами в Treeview1).
Проблема собственно в самом потоке, я не знаю как с ним работать?
Delphi
1
2
3
if FileExists(dir+'LIT\'+node.Text) then 
и
if DirectoryExists(dir+'LIT\'+node.Text) then
Delphi
1
2
3
4
5
6
7
var i,t:Integer;
node:ttreenode;
begin
for i:=0  to treeview1.Items.Count-1 do
 begin
   memo1.Lines.Add(TreeView1.Items[i].Text);//здесь полный список нодов
 end;
Отдельный поток нужен -что бы не подвисало главное окно
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.07.2012, 18:54
Ответы с готовыми решениями:

Как заставить созданный Thread работать как UI поток
Создал wpf приложение, кинул две кнопки ButtonUiTest и ButtonNonUiTest, вот обработчики кликов ...

Как создать поток (Thread) в с++ mfc?
Здравствуйте!) Не могу ни как понять, как создать поток в с++ mfc? В c# и с++ делал потоки, но в...

Как закрыть поток (Thread) чтения SerialPort
Как грамотно организовать (а главное завершать) поток чтения SerialPort? Проблемы с этим кодом: ...

Как получить Thread поток Socket.ReceiveAsync?
Имеется операция ReceiveAsync. Если не приходят никакие данные, то завершить вручную никак. вот...

14
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
13.07.2012, 22:06  [ТС] 2
так, с потоком вроде разобрался, проблема теперь другая как прикрутить эти две функции
Delphi
1
2
3
4
5
var names  : TStringList;
..........
if FileExists(dir+'LIT\'+names[i]) then 
и
if DirectoryExists(dir+'LIT\'+names[i]) then
на проверку существования папок и файлов с отображением Progressbar'а
0
429 / 337 / 36
Регистрация: 31.05.2011
Сообщений: 1,156
13.07.2012, 22:42 3
Delphi
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
TNewThread = class(TThread)
  procedure Execute; override;
  procedure Progress;
end;
...
var
  x: Integer;
...
procedure TNewThread.Execute;
var
  i: Integer;
begin
  for i := 0 to names.Count - 1 do
    begin
      if FileExists(dir+'LIT\'+names[i]) then действие;
      ...
      x := i;
      Synchronize(Progress);
    end;
end;
 
procedure TNewThread.Progress;
begin
  Form1.Progressbar.Position := x;
end;
1
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
14.07.2012, 11:07  [ТС] 4
Объясните почему так: Есть процедура автопоиска:

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var
  Dirt: string;
begin
treeview1.ClearSelection(False);
  Dirt := 'C:\';
    TreeView1.Items.BeginUpdate;
  try
    TreeView1.Items.Clear;
    GetDirectories(TreeView1, Dirt, nil, True);
    application.ProcessMessages;
  finally
    TreeView1.Items.EndUpdate;
  end;
StatusBar1.Panels[4].Text:='Автопоиск - завершен!';
процедура GetDirectories:
Delphi
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
procedure TForm1.GetDirectories(Tree: TTreeView; Directory: string;
  Item: TTreeNode; IncludeFiles: Boolean);                          //Функция Автозаполнения
var
  SearchRec: TSearchRec;
  ItemTemp: TTreeNode;
begin
  Tree.Items.BeginUpdate;
  if Directory[Length(Directory)] <> '\' then Directory := Directory + '\';
  if FindFirst(Directory + '*.*', faDirectory, SearchRec) = 0 then
  begin
    repeat
      if (SearchRec.Attr and faDirectory = faDirectory) and
      (SearchRec.Name[1] <> '.') then
      begin
        if (SearchRec.Attr and faDirectory > 0) then
          Item := Tree.Items.AddChild(Item, SearchRec.Name);
        ItemTemp := Item.Parent;
        GetDirectories(Tree, Directory + SearchRec.Name, Item, IncludeFiles);
        Item := ItemTemp;
      end
      else if IncludeFiles then
        if SearchRec.Name[1] <> '.' then
          Tree.Items.AddChild(Item, Copy(SearchRec.Name,1,length(SearchRec.Name)-4));
    until FindNext(SearchRec) <> 0;
    FindClose(SearchRec);
  end;
  Tree.Items.EndUpdate;
end;
В программе по щелчку Button- Treeview(уже заполненный) сначало очищается - потом заполняется - все элементы отображаются (т.е. видны). этот же код добавляю через поток - Treeview(но уже пустой) - заполняется элементами - НО их не видно(не отображаются) - перезапускаю программу - все элементы видны!? в чем ошибка!?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31193 / 20390 / 7941
Регистрация: 22.10.2011
Сообщений: 35,362
Записей в блоге: 6
14.07.2012, 11:14 5
Показывай код потока. Особенно интересует момент, как элементы добавляются в TreeView (из доп. потока в основной GUI-поток). Если не используется синхронизация - можешь даже не показывать, проблема в этом.
0
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
14.07.2012, 11:21  [ТС] 6
Delphi
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
100
101
102
103
104
unit Unit4;
 
interface
 
uses
  Classes, Forms, Controls, ComCtrls, SysUtils, UNit1;
 
type
  NewThead = class(TThread)
  private
    { Private declarations }
 procedure Avtopoisk;
 procedure GetDirectories(Tree: TTreeView; Directory: string;
Item: TTreeNode; IncludeFiles: Boolean);
  protected
    procedure Execute; override;
  end;
 
implementation
 
{ 
  Important: Methods and properties of objects in visual components can only be
  used in a method called using Synchronize, for example,
 
      Synchronize(UpdateCaption);  
 
  and UpdateCaption could look like,
 
    procedure NewThead.UpdateCaption;
    begin
      Form1.Caption := 'Updated in a thread';
    end; 
    
    or 
    
    Synchronize( 
      procedure 
      begin
        Form1.Caption := 'Updated in thread via an anonymous method' 
      end
      )
    );
    
  where an anonymous method is passed.
  
  Similarly, the developer can call the Queue method with similar parameters as 
  above, instead passing another TThread class as the first parameter, putting
  the calling thread in a queue with the other thread.}
 
{ NewThead }
 
procedure NewThead.Avtopoisk;//Автозаполнение
var
  Dirt: string;
begin
form1.treeview1.ClearSelection(False); //Снимаем выделение
  Dirt := 'С:\';
   form1.TreeView1.Items.BeginUpdate;
  try
    form1.TreeView1.Items.Clear; //Очищаем
    GetDirectories(form1.TreeView1, Dirt, nil, True);
  finally
    form1.TreeView1.Items.EndUpdate;
  end;
form1.StatusBar1.Panels[4].Text:='Автопоиск - завершен!';
 
end;
 
procedure NewThead.Execute;
begin
  { Place thread code here }
  Synchronize(Avtopoisk);
end;
 
procedure NewThead.GetDirectories(Tree: TTreeView; Directory: string;
  Item: TTreeNode; IncludeFiles: Boolean);     //Функция Автозаполнения
var
  SearchRec: TSearchRec;
  ItemTemp: TTreeNode;
begin
  Tree.Items.BeginUpdate;
  if Directory[Length(Directory)] <> '\' then Directory := Directory + '\';
  if FindFirst(Directory + '*.*', faDirectory, SearchRec) = 0 then
  begin
    repeat
      if (SearchRec.Attr and faDirectory = faDirectory) and
      (SearchRec.Name[1] <> '.') then
      begin
        if (SearchRec.Attr and faDirectory > 0) then
          Item := Tree.Items.AddChild(Item, SearchRec.Name);
        ItemTemp := Item.Parent;
        GetDirectories(Tree, Directory + SearchRec.Name, Item, IncludeFiles);
        Item := ItemTemp;
      end
      else if IncludeFiles then
        if SearchRec.Name[1] <> '.' then
          Tree.Items.AddChild(Item, Copy(SearchRec.Name,1,length(SearchRec.Name)-4));
    until FindNext(SearchRec) <> 0;
    FindClose(SearchRec);
  end;
  Tree.Items.EndUpdate;
end;
 
end.
И вызов из гл. окна по Button

Delphi
1
2
3
4
5
var Thea : NewThead;
begin
  Thea := NewThead.Create(True);
  Thea.FreeOnTerminate := true;
  Thea.Resume;
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31193 / 20390 / 7941
Регистрация: 22.10.2011
Сообщений: 35,362
Записей в блоге: 6
14.07.2012, 12:09 7
Лучший ответ Сообщение было отмечено volvo как решение

Решение

CHARMED, а если вот так сделать, как ты думаешь, что получится?

Delphi
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
unit Unit2;
 
interface
 
uses
  Classes, ComCtrls;
 
type
  TMyThread = class(TThread)
  private
    FItem : TTreeNode;
    FStr : string;
    { Private declarations }
    procedure GetDirectories(Directory: string;
                             Item: TTreeNode; IncludeFiles: Boolean);
  protected
    procedure Execute; override;
 
    procedure SyncStart;
    procedure SyncWork;
    procedure SyncFinish;
  end;
 
implementation
uses SysUtils, Unit1;
 
{ TMyThread }
procedure TMyThread.SyncStart;
begin
   Form1.TreeView1.ClearSelection(False);
   Form1.TreeView1.Items.Clear;
   Form1.TreeView1.Items.BeginUpdate;
end;
procedure TMyThread.SyncWork;
begin
   FItem := Form1.TreeView1.Items.AddChild(FItem, FStr);
end;
 
procedure TMyThread.SyncFinish;
begin
   Form1.TreeView1.Items.EndUpdate;
   Form1.StatusBar1.Panels[4].Text := 'Автопоиск - завершен!';
end;
 
procedure TMyThread.Execute;
var
   Dirt : string;
begin
   Synchronize(SyncStart);
   Dirt := 'С:\';
 
   GetDirectories(Dirt, nil, True);
   Synchronize(SyncFinish);
end;
 
procedure TMyThread.GetDirectories(Directory: string;
                    Item: TTreeNode; IncludeFiles: Boolean);
var
  SearchRec: TSearchRec;
  ItemTemp: TTreeNode;
begin
   Directory := IncludeTrailingPathDelimiter(Directory);
   if FindFirst(Directory + '*.*', faDirectory, SearchRec) = 0 then
   begin
      repeat
         if (SearchRec.Attr and faDirectory = faDirectory) and (SearchRec.Name[1] <> '.') then
         begin
            if (SearchRec.Attr and faDirectory > 0) then
            begin
               FItem := Item; FStr := SearchRec.Name;
               Synchronize(SyncWork);
               // Item := Tree.Items.AddChild(Item, SearchRec.Name);
               Item := FItem;
            end;
            ItemTemp := Item.Parent;
            GetDirectories(Directory + SearchRec.Name, Item, IncludeFiles);
            Item := ItemTemp;
         end
         else if IncludeFiles then
            if SearchRec.Name[1] <> '.' then
            begin
               FItem := Item; FStr := Copy(SearchRec.Name, 1, Length(SearchRec.Name) - 4);
               Synchronize(SyncWork);
               // Tree.Items.AddChild(Item, Copy(SearchRec.Name,1,length(SearchRec.Name)-4));
            end;
      until FindNext(SearchRec) <> 0;
      FindClose(SearchRec);
   end;
end;
 
end.
1
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
14.07.2012, 12:19  [ТС] 8
UI,
Вообще ничего не находит...
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31193 / 20390 / 7941
Регистрация: 22.10.2011
Сообщений: 35,362
Записей в блоге: 6
14.07.2012, 12:35 9
Да? Ну, смотри:
1
Миниатюры
Поток - Thread, как с ним работать  
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
14.07.2012, 12:49  [ТС] 10
UI, сори, а как Вы вызвали процедуру по кнопке(что прописали)!?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31193 / 20390 / 7941
Регистрация: 22.10.2011
Сообщений: 35,362
Записей в блоге: 6
14.07.2012, 12:53 11
А то же, что и у тебя:

Delphi
1
2
3
4
5
6
7
8
procedure TForm1.Button7Click(Sender: TObject);
var
  Thea: TMyThread;
begin
   Thea := TMyThread.Create(True);
   Thea.FreeOnTerminate := true;
   Thea.Resume;
end;
1
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
14.07.2012, 12:56  [ТС] 12
UI,
Скиньте Пожалуйста Ваш проект - с рисунка, У меня вообще ничего не происходит
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31193 / 20390 / 7941
Регистрация: 22.10.2011
Сообщений: 35,362
Записей в блоге: 6
14.07.2012, 13:17 13
Что, и в StatusBar ничего не выводится? Значит, еще не закончил работу поток. Ты на папке меньшего размера проверь для начала, а потом будешь на всём диске экспериментировать.

Вот проект:
1
Вложения
Тип файла: zip vcl10_2.zip (7.5 Кб, 15 просмотров)
89 / 70 / 9
Регистрация: 04.03.2012
Сообщений: 206
14.07.2012, 13:43  [ТС] 14
так в том то и дело что в статус баре Сразу после нажатия на кнопку пишет Автопоиск завершен! а Treeview пустой, ладно сейчас глянем...Спасибо


Не по теме:

блин..............

СПАСИБО большое Все работает, Скопировал Ваш UNit полностью - поменял только путь - и все работает так как надо,

Добавлено через 11 минут
Можно еще один вопрос, насколько я понял - Один поток - одна функция(как у меня только автопоиск), - т.е. в этот же поток я не смогу например вставить функции сохранения и загрузки того же TreeView - нужно делать отдельные потоки для этого?
0
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
31193 / 20390 / 7941
Регистрация: 22.10.2011
Сообщений: 35,362
Записей в блоге: 6
14.07.2012, 13:50 15
Если сохранение/загрузка дерева не связаны по времени с его заполнением - то делай другой поток. Если, скажем, сразу после заполнения ты хочешь сохранять дерево - то можно добавить этот функционал в существующий поток.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
14.07.2012, 13:50

Std::thread как усыпить/ пробудить поток?
Есть ли в std::thread возможность как - то приостановить поток, не разрушая его, а потом, по какому...

Как разбудить поток после команды Thread.sleep(t) ?
Подскажите, как разбудить поток после команды Thread.sleep(t), не используя многопотоковость?...

Почему при Thread.Abort закрывается программа? Как остановить поток?
Есть класс для инвертирования движения мыши. При вызове метода Stop программа продолжает работать....

Как правильно работать с Thread?
Есть два потока А и B. Поток А печатает «Left», поток B печатает «Right». Модифицируйте...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.