общая схема:
------
есть программа.. многопоточная скачка с FTP
(не смейтесь... стандарт проги типа Getright не подходят — данные специфичые)
но в ходе работы потоков бывает связь с FTP впадает в глубокий зависон(я так понял вешается Data chanel при
передачи потока данных).
Есть идея перед началом работы потока поставить таймер с интервалом например 3 мин. если по истечении этого
интервала работа скачка все еще висит то kill ей ... , ... и поновой закачка идет.
------
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
От:
Аноним
Дата:
10.11.03 15:35
Оценка:
Здравствуйте, vtroitsk, Вы писали:
V>общая схема: V>------ V> есть программа.. многопоточная скачка с FTP V> (не смейтесь... стандарт проги типа Getright не подходят — данные специфичые)
ХА ХА ХА ХО ХО ...
V>как в потоке грамотоно создать таймер...
Можно попробовать SetTimer внутри потока и в качестве ID таймера задать Handle потока.
Мессаги все равно будет получать основной поток, при получении мессаги от таймера — грохать поток с ID таймера.
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
Значит, так, с потоками я не работал, по большому счету, а Дельфей под руками нет. Поэтому у меня не ответ, а вопрос. Когда мы создаем таймер, к какому окну дельфи его привязывает (see WinAPI SetTimer)? Подозреваю, что к Application
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
Здравствуйте, Slicer [Mirkwood], Вы писали:
SM>Значит, так, с потоками я не работал, по большому счету, а Дельфей под руками нет. Поэтому у меня не ответ, а вопрос. Когда мы создаем таймер, к какому окну дельфи его привязывает (see WinAPI SetTimer)? Подозреваю, что к Application
Нет. Создается специальное окно. UTSL:
Мы чего хотим — чтобы сообщения от таймера обрабатывались, а в
отдельном потоке выполнялся Download. А чего написали? Чтобы в
отдельном потоке создавался таймер, а потом в нем же выполнялся
download. А кто будет сообщения от таймера проверять — они ведь
будут появляться в его же потоке?
Вариант:
Procedure StartDownload;
var T:TThread;
begin
fd_Timer:=TMyTimer.Create(nil);
fd_Timer.Enabled:=true;
T:=TMyThread.Create(true);
T.ChildTimer:=TMyTimer.Create(nil);
T.ChildTimer.enabled:=nil;
T.Resume();
//А можно всю эту дребедень в конструктор передать, правда,
придется новый конструктор писать
end;
Type
TMyThread = class(TThread)
.......
ChildTimer :TMyTimer;
.......
end;
TMyThread.Execute
begin
Download //моя процедура любящая зависать надолго....
ChildTimer.enabled:=false;
ChildTimer.free;
end;
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[4]: Delphi. как грамотно создать и исп-ть Timer в Thr
... SM>Мы чего хотим — чтобы сообщения от таймера обрабатывались, а в SM>отдельном потоке выполнялся Download. А чего написали? Чтобы в SM>отдельном потоке создавался таймер, а потом в нем же выполнялся SM>download. А кто будет сообщения от таймера проверять — они ведь SM>будут появляться в его же потоке?
..
несовсем так.
есть поток.в нем Download (без всякой визуальщины... формы нет )
таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)
Re[5]: Delphi. как грамотно создать и исп-ть Timer в Thr
Здравствуйте, vtroitsk, Вы писали:
V>несовсем так. V> есть поток.в нем Download (без всякой визуальщины... формы нет ) V> таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)
Чур меня! Это как — таймер как переменная класса потока?!
И зачем тебе таймер обязательно в этот поток запихивать? Определист — доп. поток тебе нужен чтобы в нем производить Download или чтобы в нем отображать прогресс? По условию твоей задачи (т.е. визуальное "неповисание") это должны быть разные потоки!
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[5]: Delphi. как грамотно создать и исп-ть Timer в Thr
Здравствуйте, vtroitsk, Вы писали:
V>... SM>>Мы чего хотим — чтобы сообщения от таймера обрабатывались, а в SM>>отдельном потоке выполнялся Download. А чего написали? Чтобы в SM>>отдельном потоке создавался таймер, а потом в нем же выполнялся SM>>download. А кто будет сообщения от таймера проверять — они ведь SM>>будут появляться в его же потоке? V>..
V>несовсем так. V> есть поток.в нем Download (без всякой визуальщины... формы нет ) V> таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)
Гм. А зачем там вообще таймер?
Для его работы, в Download надо будет периодически вызывать:
— что-то типа PeekMessages — для обработки сообщений для таймера
— проверять состояние таймера.
Не проще ли в начале Download получить текущее время (GetTickCount) и дальше сверяться с ним?
Re[5]: Delphi. как грамотно создать и исп-ть Timer в Thr
Здравствуйте, vtroitsk, Вы писали: V>несовсем так. V> есть поток.в нем Download (без всякой визуальщины... формы нет ) V> таймер тоже в этом потоке должон быть.... . (он как переменная класса потока объявлен)
Неважно, где он объявлен. Если ты его создаешь внутри метода Execute, то все сообщения от таймера будут приезжать именно в этот поток. И он обязан делать message pump. А если создавать его за пределами метода Execute (можно даже в конструкторе треда, не только во внешнем коде), то сообщения таймера будут приезжать в другой поток (скорее всего в главный).
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[6]: Delphi. как грамотно создать и исп-ть Timer в Thr
Здравствуйте, Sinclair, Вы писали:
S>Неважно, где он объявлен. Если ты его создаешь внутри метода Execute, то все сообщения от таймера будут приезжать именно в этот поток. И он обязан делать message pump. А если создавать его за пределами метода Execute (можно даже в конструкторе треда, не только во внешнем коде), то сообщения таймера будут приезжать в другой поток (скорее всего в главный).
ну, если быть точным, то в вызывающий а так — все верно...
... << RSDN@Home 1.1.0 stable >>
Если при компиляции и исполнении вашей программы не происходит ни одной ошибки — это ошибка компилятора :)))
Re: Delphi. как грамотно создать и исп-ть Timer в Thread
Здравствуйте, vtroitsk, Вы писали:
V>общая схема:
V>как в потоке грамотоно создать таймер...
в потоке нельзя использовать таймеры , надо пользовться функциями ожидания
самый простой вариант :
I:=1000*60*3; // 3 минуты
Sleep(i);
но он не точный — время ожидания зависит от планировщика потоков (приоритета потоков итд )
для более точных интревалов надо использовать объект ядра "ожидаемый таймер" (WaitableTimer)
как уже отвечали выше.
вообще рекомндую почитать Рихтера "Windows для профессионалов", для такой задачи (многопоточная закачка)
IMHO это необходимо ...
... << RSDN@Home 1.1 beta 2 >>
Re[2]: Delphi. как грамотно создать и исп-ть Timer в Thr
Для работы с сетью в потоке используй блокирующий тип сокета, и поток TWinSocketStream
У него есть функция WaitForData с указанием тайм-аута.
Если данные не пришли, то можешь завершать поток
если пришли — сам знаешь что с ними делать.
Re[2]: Delphi. как грамотно создать и исп-ть Timer в Thr
program Proof;
{$APPTYPE CONSOLE}uses windows;
function Thread(Parameter:pointer):dword; stdcall;
var idTimer:dword;
M:TMsg;
begin
idTimer:=SetTimer(0,0,1000,nil);
while integer(GetMessage(M,0,0,0))>0 do
begin
TranslateMessage(M);
if (M.Message=WM_TIMER) then writeln('WM_TIMER');
DispatchMessage(M);
end;
KillTimer(0,idTimer);
result:=0;
end;
var
idThread:dword;
begin
CreateThread(nil, 0, @Thread, nil, 0, idThread);
readln;
end.
Tested on FPC 1.0.10.
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[3]: Delphi. как грамотно создать и исп-ть Timer в Thr
Здравствуйте, Slicer [Mirkwood], Вы писали:
D_T>>в потоке нельзя использовать таймеры
это смотря какие таймеры использовать, TTimer в потоке не прокатит
в вопросе же спрашивалось про него , а не про API функции
кроме того, как в этом примере добитьcя интервала срабатывания в 500 наносекунд? SM>
да, так конечно можно, но это IMHO извращениее,
если в потоке не используюся сообщения,
то цикл опроса сообщений — лишнее и IMHO это плохой стиль программирования SM>Tested on FPC 1.0.10.
SM>Slicer
... << RSDN@Home 1.1.0 stable >>
Re[4]: Delphi. как грамотно создать и исп-ть Timer в Thr
Здравствуйте, Denis_TST, Вы писали:
D_T>то цикл опроса сообщений — лишнее и IMHO это плохой стиль программирования
А позволить кому-то загадить твоему потоку очередь сообщений PostThreadMessage-ом (ведь, выходит, ее никто и разгребать не будет, раз нет message-pump) — и вовсе никудышный стиль программирования Разве что поток таков, что очередь для него не создается вообще.
Slicer
Специалист — это варвар, невежество которого не всесторонне :)
Re[3]: Delphi. как грамотно создать и исп-ть Timer в Thr
От:
Аноним
Дата:
15.11.03 08:10
Оценка:
Здравствуйте, Slicer [Mirkwood], Вы писали:
SM> if (M.Message=WM_TIMER) then writeln('WM_TIMER');
В потоке нельзя использовать writeln
Т.е., в данном случае, лучше WriteFile