Форум: "Начинающим";
Текущий архив: 2009.06.07;
Скачать: [xml.tar.bz2];
ВнизПрограмма подвисает при запуске цикла Найти похожие ветки
← →
djkondakov (2009-04-23 15:34) [0]Требуется написать программу, которая копирует файлы, пути к которым записаны в TListBox"е, в новое место. Я хотел сделать по старинке, как в Паскале - цикл по записям в списке, а внутри его - цикл по байтам файла. Однако при запуске копирования программа перестает отвечать, и "висит" вплоть до окончания копирования. Пробовал использовать CopyFrom и TTimer, результат тот же. Может, кто знает - как сделать цикл без подвисания программы?
← →
Медвежонок Пятачок © (2009-04-23 15:38) [1]она не подвисает.
← →
Сергей М. © (2009-04-23 15:38) [2]Вынести логику копирования в доп.код.поток, ибо за интерактив отвечает главный поток
← →
stas © (2009-04-23 15:43) [3]Паралельный поток создавайте.
копировать файлы можно с помощью функции- Copyfile
← →
djkondakov (2009-04-23 15:51) [4]А без использования потоков никак нельзя? Просто я еще не очень-то в них...
← →
Сергей М. © (2009-04-23 15:54) [5]Можно и без доп.потоков.
Но это лишь уменьшит эффект "зависания", но избавит от него совсем.
← →
Anatoly Podgoretsky © (2009-04-23 15:59) [6]Лучшее - shFileOperation
Потоки вообще не нужны при указаном тобой алгоритме, обновлять можно хоть через байт, а ты видимо ни разу.
Код давай.
← →
djkondakov (2009-04-23 16:13) [7]Угу, принимайте.
procedure TForm1.Button7Click(Sender: TObject);
var stream1, stream2: TFileStream;
i: integer;
begin
if edit1.Text<>"" then
timer1.Enabled:=true
else showmessage("Не указана папка назначения!");
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var stream1, stream2: TFileStream;
i: integer;
begin
if i<=listbox1.Items.Count-1 then begin
try
stream1:=tfilestream.create(listbox2.items[i], fmopenread);
stream2:=tfilestream.create(edit1.text+listbox1.items[i], fmcreate);
stream2.seek(0,sofromend);
stream2.CopyFrom(stream1, stream1.size);
finally
stream1.free;
stream2.free;
end;
i:=i+1;
end else begin
timer1.Enabled:=false;
showmessage("Копирование завершено");
end;
end;
Вот. Пояснение - в ListBox1 хранятся имена файлов без пути, а в ListBox2 - полные имена, с путями.
← →
Anatoly Podgoretsky © (2009-04-23 16:15) [8]> djkondakov (23.04.2009 16:13:07) [7]
Ну и где же тут цикл по байтам?
← →
djkondakov (2009-04-23 16:18) [9]Цикл по байтам я убрал, когда бился с "зависанием". В итоге ничего не изменилось.
← →
Anatoly Podgoretsky © (2009-04-23 16:21) [10]> djkondakov (23.04.2009 16:18:09) [9]
Изменилось и еще как - ты сделал "зависание".
← →
Медвежонок Пятачок © (2009-04-23 16:25) [11]В итоге ничего не изменилось.
сын: - Папа, почему солнце всегда восходит на востоке, а заходит на западе?
папа-программист: - Это точно?
- Ага!
- Проверял?
- Проверял!!!
- Ничего не трогай, пусть так и работает!
← →
djkondakov (2009-04-23 16:27) [12]Понятно. Делаю обратно циклы.
← →
Anatoly Podgoretsky © (2009-04-23 16:42) [13]> djkondakov (23.04.2009 16:27:12) [12]
Не надо делать циклы, по крайней мере по байтам, смотри в сторону shFileOperation или в крайнем случае в сторону CopyFileEx
← →
Сергей М. © (2009-04-23 16:43) [14]
> Делаю обратно циклы
Не надо ни "обратно" ни вновь)
Можно и без явных циклов обойтись - он уже есть, только неявный.
Все что нужно - сделать свой наследник TFileStream и в нем перекрыть, например, метод Read.
В теле перекрытого метода ограничивать размер запрашиваемых к чтению блоков, например, 4-мя килобайтами. После чтения очередного блока тут же вызывать Application.ProcessMessages.
← →
Сергей М. © (2009-04-23 16:44) [15]
> Anatoly Podgoretsky © (23.04.09 16:42) [13]
> CopyFileEx
Она, если не ошибаюсь, такая же блокирующая как и CopyFile
← →
djkondakov (2009-04-23 16:58) [16]С циклами виснет, хотя файлы копируются. Скрин не могу выложить, т.к. не могу его сделать. Если во время работы переключиться в другое окно, то на поверхности окна программы остается кусок текущего окна. Передвигать по экрану окно программы нельзя.
← →
Медвежонок Пятачок © (2009-04-23 17:01) [17]тяжелый случай .....
← →
Anatoly Podgoretsky © (2009-04-23 17:02) [18]> Сергей М. (23.04.2009 16:44:15) [15]
Не забывай про функцию обратного вызова, поэтому полублокирующая, точно также как запись кусками с потомщью TFileStream
← →
Anatoly Podgoretsky © (2009-04-23 17:03) [19]> Медвежонок Пятачок (23.04.2009 17:01:17) [17]
Надежда есть - кусок кода один раз привел.
← →
Сергей М. © (2009-04-23 17:07) [20]
> Anatoly Podgoretsky © (23.04.09 17:02) [18]
Толку-то от колбэка ?
Вызвавший ф-цию код все равно будет "висеть" до фактического окончания копирования..
Да и колбек будет вызываться с частотой, определяемой системой, а не с той с которой было бы желательно для своевременной обработки оконных сообщений
← →
Сергей М. © (2009-04-23 17:10) [21]
> точно также как запись кусками с потомщью TFileStream
Здесь хотя бы размеры копируемых порций можно контролировать, в отличие от CopyFileEx
← →
Ганя (2009-04-23 17:18) [22]Копирование файлов - это основная цель программы? Может ли пользователь продолжать работать в программе, пока файлы копируются, или он должен ждать результатов, и максимум, что ему может быть позволено - отменить процесс копирования?
← →
djkondakov (2009-04-23 17:19) [23]Да, это основная цель программы. Пользователь должен видеть прогресс, ему должно сообщаться, сколько из скольки файлов скопировано.
← →
djkondakov (2009-04-23 17:22) [24]Индикацию прогресса я как раз сделать не могу, т.к. при копировании у программы не остается времени на отрисовку оконных элементов.
← →
Сергей М. © (2009-04-23 17:25) [25]
> при копировании у программы не остается времени на отрисовку
> оконных элементов
Так ты сам не даешь ей это время, потому и не отрисовывает)
← →
djkondakov (2009-04-23 17:28) [26]А как ей, собсно, дать это время? Может, попробовать в цикл sleep запихать?
← →
AndreyV © (2009-04-23 17:36) [27]> [26] djkondakov (23.04.09 17:28)
> А как ей, собсно, дать это время? Может, попробовать в цикл
> sleep запихать?
Ты ответы читал, особенно [4]?
← →
Сергей М. © (2009-04-23 17:36) [28]Следует, к примеру, вызвать Application.ProcessMessages.
Сделать это можно в колбэк-функции при использовании CopyFileEx или в теле перекрытого TFileStream.Read (cм. [14])
← →
Ганя (2009-04-23 17:50) [29]
> Да, это основная цель программы. Пользователь должен видеть
> прогресс, ему должно сообщаться, сколько из скольки файлов
> скопировано.
Да, при таком раскладе городить огород с потоками не имеет смысла, присоединяюсь к [28]
← →
djkondakov (2009-04-23 18:08) [30]Ясно, буду разбираться... Всем спасибо, если что, буду спрашивать здесь.
← →
Anatoly Podgoretsky © (2009-04-23 18:49) [31]> Сергей М. (23.04.2009 17:07:20) [20]
Толк есть, оно в первую очередь предназначено для организации прогресса, значит обработки событий.
← →
Anatoly Podgoretsky © (2009-04-23 18:52) [32]
> Да, это основная цель программы. Пользователь должен видеть
> прогресс, ему должно сообщаться, сколько из скольки файлов
> скопировано.
Это вообще другая постановка, между обработкой файлов достаточно времени, что бы показать любого размера видеофайл
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2009.06.07;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.004 c