Приложение (MFC, API) CDialog предназначено для синхронизации данных между флешкой и РС.
Обработка данных ведется в многопотоковом режиме. В момент выполнения задач (копирование, перемещение, удаление и т.д) выводится результат выполнения текущей операции в CListCtrl. Прогрес выполнения отражается в прогрес-баре. Все это происходит, если exeшник находится на HDD (запущен с hdd или дискеты fdd).
При старте с флешки (съемный накопитель), приложение визуально "замерзает" на время исполнения , а после виден только конечный результат работы программы.
Подскажите пожалуйста решение или направление решения проблемы.
(приложение копирует файлы на 30% бысрее, чем это делает explorer).
Я писал и отлаживал приложение на винте, а на флешке не пробовал. Вот запустил экзешник с флешки и, ОБЛОМ.
20.09.05 18:25: Перенесено модератором из 'WIN API' — Odi$$ey
Разница, конечно, есть. При старте с флеша приложение ИМХО переписывается в своп-файл , так как может потребоваться подкачка страниц, а флешку ты можешь и вытащить. Во всяком случае, такое имеет место, по утверждению Рихтера, при старте с дискеты.
Но это ИМХО мало что объясняет в твоем случае...
Попробуй сделать простое тестовое приложение. К примеру, диалог на MFC с прогресс-баром, обновляемым по таймеру, и чтобы на все требовалось 1-2 минуты. Будет тот же эффект или нет ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gibruway, Вы писали:
PD>Разница, конечно, есть. При старте с флеша приложение ИМХО переписывается в своп-файл , так как может потребоваться подкачка страниц, а флешку ты можешь и вытащить. Во всяком случае, такое имеет место, по утверждению Рихтера, при старте с дискеты. PD>Но это ИМХО мало что объясняет в твоем случае... PD>Попробуй сделать простое тестовое приложение. К примеру, диалог на MFC с прогресс-баром, обновляемым по таймеру, и чтобы на все требовалось 1-2 минуты. Будет тот же эффект или нет ?
В том-то и дело. Сообщения, которые передаются контролам Диалога
из потоков, которые создаются в цикле. Как бы толпятся и ждут окончания последнего потока. А потом за секунду все выполняются в соответствующей последовательности. А в случае, если экзешник запустить с винта, сообщения выполняются своевременно, еще в момент выполнения потока (движется прогрес-бар, ставятся галочки в списке задач, доступны или активны кнопки диалога).
Здравствуйте, gibruway, Вы писали:
G>Здравствуйте, Pavel Dvorkin, Вы писали:
G>В том-то и дело. Сообщения, которые передаются контролам Диалога G>из потоков, которые создаются в цикле. Как бы толпятся и ждут окончания последнего потока.
Не совсем понял, поясни. Поток == thread ? Тогда как они создаются и т.д. ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gibruway, Вы писали:
G>>Здравствуйте, Pavel Dvorkin, Вы писали:
G>>В том-то и дело. Сообщения, которые передаются контролам Диалога G>>из потоков, которые создаются в цикле. Как бы толпятся и ждут окончания последнего потока.
PD>Не совсем понял, поясни. Поток == thread ? Тогда как они создаются и т.д. ?
Сперва программа анализирует синхронизируемые файлы и создает список процедур (копирование, перемещение, удаление и т.д.). Параллельно добавляются строки в CListCtrl, отображая содержимое списка процедур. Далее можно редактировать список процедур синхронизации (исключать или изменять строки).
Функция диалога "старт" перебирает в цикле список процедур и создает Поток == thread,
вызывая в нем соответствующую функцию (копирование, перемещение, удаление и т.д.). Сколько строк в списке, столько и потоков.
Каждый поток == thread в процессе своей работы делает отметку в CListCtrl об успешности выполнения отведенной ему задачи, двигает прогресс-бар и т.д.
G>Каждый поток == thread в процессе своей работы делает отметку в CListCtrl об успешности выполнения отведенной ему задачи, двигает прогресс-бар и т.д.
Как он это делает, расскажи подробнее. Ты в курсе, что из чужого потока нельзя вызывать члены CListCtrl ? Что там — PostMessage , PostThreadMessage или что-то еще ?
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gibruway, Вы писали:
G>>Каждый поток == thread в процессе своей работы делает отметку в CListCtrl об успешности выполнения отведенной ему задачи, двигает прогресс-бар и т.д.
PD>Как он это делает, расскажи подробнее. Ты в курсе, что из чужого потока нельзя вызывать члены CListCtrl ? Что там — PostMessage , PostThreadMessage или что-то еще ?
ST* s=new ST(ListTasksResultCtrl,ProgressTasksCtrl,s_path,e_path,i);
thred=AfxBeginThread(thredCopy,s,THREAD_PRIORITY_NORMAL); // в цикле создаются потоки
//
в потоке обращение к CListCtrl TList
item.iItem = index;
item.iImage = 5;
TList.SetItem(&item); // TList == ListTasksResultCtrl
Здравствуйте, gibruway, Вы писали:
G>Приложение (MFC, API) CDialog предназначено для синхронизации данных между флешкой и РС. G>Обработка данных ведется в многопотоковом режиме. В момент выполнения задач (копирование, перемещение, удаление и т.д) выводится результат выполнения текущей операции в CListCtrl. Прогрес выполнения отражается в прогрес-баре. Все это происходит, если exeшник находится на HDD (запущен с hdd или дискеты fdd). G>При старте с флешки (съемный накопитель), приложение визуально "замерзает" на время исполнения , а после виден только конечный результат работы программы.
На мой взгляд, поведение странное. Сколько запускал всего с флэша — подобное не встречал. Воспроизволдится ли это на других OS/flashdrive/что_там_ещё? Может, флэшка с шифрованием каким-то и это как-то сказывается?
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Здравствуйте, gibruway, Вы писали:
G>в потоке обращение к CListCtrl TList G>item.iItem = index; G>item.iImage = 5; G>TList.SetItem(&item); // TList == ListTasksResultCtrl
Нельзя так делать. Классы MFC не являются потокобезопасными, поэтому вызывать их функции из других потоков нельзя. Надо послать сообщение (PostMessage, PostThreadMessage) из другого потока основному (т.е. тому, где TList создан), а он пусть добавляет.
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, gibruway, Вы писали:
G>>Приложение (MFC, API) CDialog предназначено для синхронизации данных между флешкой и РС. G>>Обработка данных ведется в многопотоковом режиме. В момент выполнения задач (копирование, перемещение, удаление и т.д) выводится результат выполнения текущей операции в CListCtrl. Прогрес выполнения отражается в прогрес-баре. Все это происходит, если exeшник находится на HDD (запущен с hdd или дискеты fdd). G>>При старте с флешки (съемный накопитель), приложение визуально "замерзает" на время исполнения , а после виден только конечный результат работы программы.
GN>На мой взгляд, поведение странное. Сколько запускал всего с флэша — подобное не встречал. Воспроизволдится ли это на других OS/flashdrive/что_там_ещё? Может, флэшка с шифрованием каким-то и это как-то сказывается?
Пробовал на других флешках. Результат не изменился. Приблизительно 80% работы программы проходит при не активном окне, а после, процесс проходит, как надо.
Re[8]: Какая разница, откуда стартует экзешник?
От:
Аноним
Дата:
23.09.05 06:49
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, gibruway, Вы писали:
G>>в потоке обращение к CListCtrl TList G>>item.iItem = index; G>>item.iImage = 5; G>>TList.SetItem(&item); // TList == ListTasksResultCtrl
PD>Нельзя так делать. Классы MFC не являются потокобезопасными, поэтому вызывать их функции из других потоков нельзя. Надо послать сообщение (PostMessage, PostThreadMessage) из другого потока основному (т.е. тому, где TList создан), а он пусть добавляет.
В данном конкретном случае так можно делать, потому что CListCtrl::SetItem в итоге просто вызывает функцию SendMessage. А вот PostMessage я бы тут не рекомендовал, потому что с его помощью довольно сложно передавать различные структуры.