Форум: "Основная";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];
ВнизОбработка файлов в потоке Найти похожие ветки
← →
Sergey_R © (2005-10-05 10:48) [0]Есть прога, которая скагирует все mp3"ки и читает из них теги. Для тысячи файлов все вроде работает быстро, а вот если сканировать всю музыку(около 9000 файлов), то что-то очень долго. Можно ли как-то выненсти чтение файлов отдельный поток и выводить индикатор прогресса (ProgressBar или чтто-нибудь типа него)
← →
Владислав © (2005-10-05 11:08) [1]Как-нибудь можно вынести в поток. И прогресс показать. Только сканировать быстрее от этого не станет.
← →
Smithson © (2005-10-05 11:17) [2]Чего получить-то хочется? Ускорить процесс будет сложно, а вот нарисовать индикатор - вполне реально. Причем проще его отрисовывать в том же потоке, что и поиск, после обработки каждого n-го файла (n => 1 ;)). Только перед этим надо подсчитать количество файлов, попадающих под обработку. Тот же поиск, но просто подсчет. Потери времени на этот поиск, в принципе, на системе NTFS даже окупятся, поскольку каталоги закешируются и при отсутсвии интенсивного файлового обмена на машине следующий поиск по этим каталогам пойдет существенно быстрее.
← →
TUser © (2005-10-05 11:19) [3]Процесс ускорится если есть два (и более) процессора или если файлы располагаются на более чем одном жестком диске (не логическом, а именно HDD - и при этом надо по-умному организовать работу потоков, например, каждый поток сканирует свой диск).
← →
Sergey_R © (2005-10-05 11:44) [4]Мне это нужно не для ускорения поиска, а чтобы пользователь знал, что программа не повисла, а выполняет какие-то действия!
← →
TUser © (2005-10-05 11:48) [5]Ну и прекрасно - сделай себе наследника от TThread, напиши ему в методе Execute
while not Terminated do begin
<некоторый повыторяемый код>
Synchronize(<метод этого класса, кторый апдейтит ProgressBar>);
sleep(0);
end;
А на этой формочке, где PB лежит положи кнопочку с надписью Отмена и по ее нажатии делай MyThread.Terminate.
См. также свойство TThread.FreeOnTerminated - может быть полезно
← →
Sergey_R © (2005-10-09 12:13) [6]А зачем нужен Sleep(0)? Вроде ничего и не произойдет, если его убрать!
← →
GuAV © (2005-10-09 12:48) [7]TUser © (05.10.05 11:48) [5]
Synchronize(<метод этого класса, кторый апдейтит ProgressBar>);
Synchronize - IMHO неоправданная роскошь для этого случая. PostMessage вполне хватит.
← →
Sergey_R © (2005-10-09 14:47) [8]Короче создал я Unit3, где написал:
unit Unit3;
interface
uses
Classes;
type
TMyThread = class(TThread) //Новый класс
private
answer: Integer;
protected
procedure ShowResult;
procedure Execute; override;
end;
implementation
uses
SysUtils, Unit1;
//Процедура для вывода информации из потока
procedure TMyThread.ShowResult;
begin
Form1.Edit2.Text := IntToStr(answer);
end;
//Длинная процедура
procedure TMyThread.Execute;
var
i: Integer;
begin
for i := 1 to 10000 do
begin
answer := answer + 1;
Synchronize(ShowResult);
end;
end;
end.
На 1 форме создал Button6procedure TForm1.Button6Click(Sender: TObject);
var
MyThread: TMyThread;
begin
MyThread := TMyThread.Create(False);
end;
и Edit2, куда выводятся данные потока.
Но почему-то ничего не работает (поток даже не запускается!),
а после закрытия формы вылазит ошибка
Exception EAccessViolation in module Project1.exe at 0001A6C8...
Но! Если создать новое приложение,
в Unit2 которого занести поток,
то все работает отлично! Почему так?
← →
Zeqfreed © (2005-10-09 14:54) [9]Sergey_R © (09.10.05 14:47) [8]
procedure TMyThread.Execute;
var
i: Integer;
begin
FreeOnTerminate := true;
for i := 1 to 10000 do
begin
answer := answer + 1;
Synchronize(ShowResult);
end;
end;
procedure TForm1.Button6Click(Sender: TObject);
begin
TMyThread.Create(False);
end;
Скорее всего из-за этого AV было.
> поток даже не запускается!
Как проверил?
← →
Sergey_R © (2005-10-09 15:02) [10]> Как проверил?
В Edit2 ничего не выводится, а когда добавил в поток ShowMessage("aaa"); то он не появился! Dialogs в Uses писал!
← →
Zeqfreed © (2005-10-09 15:09) [11]Sergey_R © (09.10.05 15:02) [10]
Проверил - твой код с моими изменениями работает.
Проверил - твой код без моих изменений работает.
← →
Sergey_R © (2005-10-09 15:19) [12]У меня тоже все работает, если создавать новый проект! А вот если добавлять код в ГОТОВОЕ приложение, то ничего не работает! Вот это я и не понимаю...
← →
Zeqfreed © (2005-10-09 15:31) [13]Sergey_R © (09.10.05 15:19) [12]
У тебя ошибка в программе!
← →
Sergey_R © (2005-10-09 15:35) [14]Да где там может быть ошибка, если я всего-то добавил 2 компонента и один модуль? Исходный текст (добавленный) такой же, как я и написал!
← →
Zeqfreed © (2005-10-09 15:43) [15]Sergey_R © (09.10.05 15:35) [14]
Так известно где - в 17-ой строке.
← →
andrexa © (2005-10-11 07:42) [16]народ, потоки - псевдорешение, при кажущемся облегчении задачи они зачастую её усложняют на порядок, выводи индикатор, или в цикле показывай анимацию..... В конце концов ставьте Application.ProcessMessages
и обрабатывайте кнопку "прервать"
← →
Digitman © (2005-10-11 08:31) [17]
> Sergey_R © (09.10.05 15:19) [12]
"так работает, а эдак не работает" ...
а отладчик на что существует, спрашивается ?!
← →
Bel © (2005-10-11 09:14) [18]> Sergey_R © (09.10.05 12:13) [6]
>
> А зачем нужен Sleep(0)? Вроде ничего и не произойдет, если его убрать!
Произойдет передача процессорного времени другому потоку в очереди.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2005.10.30;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.049 c