Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2009.06.07;
Скачать: CL | DM;

Вниз

Программа подвисает при запуске цикла   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.54 MB
Время: 0.014 c
2-1240213953
Iriss
2009-04-20 11:52
2009.06.07
Потоки


3-1222029089
Раиса
2008-09-22 00:31
2009.06.07
ClientDataSet и Insert .... select ... from что?


15-1238775478
Garfunkel
2009-04-03 20:17
2009.06.07
TMidiGen - модуль для создания midi звуков


15-1238616770
Артур Пирожков
2009-04-02 00:12
2009.06.07
Как вытащить звук из ютьбовского ролика?


2-1240313348
kostyl_kostyl
2009-04-21 15:29
2009.06.07
Как нарисовать на форме полупрозрачный полигон?