Создаю несколько потоков с помощью CreateThread. Внутри каждого идет обращение к сайту (в каждом потоке свой сайт). Если пользователю надоело ждать, он нажимает "Стоп". Поиск должен остановится. Сначала у меня сайты опрашивались последовательно, при нажатии на "Стоп" переменной присваивалось специальное значение, а внутри потока эта переменная постоянно проверялась и поток отключался, если появлялось нужное значение. Но был и минус: приходилось ждать завершения текущего действия (InternetConnect, HttpOpenRequest, HttpSendRequest, InternetReadFile). Т.е. в любом случае была задержка, иногда довольно большая. Теперь хочется сделать нормально. СloseHandle не работает (хотя я так и не понял должен ли он тут срабатывать). PS Нормально ли таким жестоким способом прерывать InternetConnect, или же нужно дожидаться завершения текущего действия и делать InternetCloseHandle для каждого этапа?
если процессы разные - не нада. убить процесс см. TerminateProcess а если потоки, и процесс один - лучше подожди, т.к. при очень длительной работе весь этот хлам может скапливаться многократно
max7C4, да-да процесс один. Действительно будет скапливаться эта муть. Но сайты иногда с таким скрипом отвечают, плюс скорость соединения далеко не всегда приемлемая. эх. а грохнуть поток как-то снаружи можно?
Вот блин! Точно! А в описании CreateThread среди ссылок на связанные функции ничего такого нету GoldFinch, а вы сами, что посоветуете, грохать поток сразу или ждать завершения текущей операции и закрывать интернет соединение?
provocateur а кто его знает хорошо это или плохо... может стоит посмотреть в сторону асинхронного режима?
GoldFinch, или я в английском не силен, или просто не понимаю какая разница как дожидаться окончания выполнения функции. У меня и так для каждого соединения свой поток, внутри него я комфортно получаю данные от InternetReadFile. А что мне дает использование InternetSetStatusCallback?
Partner прав. асинхронная работа тут рулит. при использовании асинхронного режима не обязательно ждать завершения текущего действия, его можно тупо прервать.
SlyBit, довольно сложно на сокетах городить огород. непонятно куда денутся задержки: соединиться нужно, получить данные нужно. скорость интернет соединения у всех разная. Partner, Freeman, буду читать. Не вся сразу дается.
Freeman +1 имеется ввиду, что ты попросил систему, и система за тебя сама присоединится, подождет данные и, как данные будут приняты, сообщит тебе об этом, но такое действие всегда можно попросить прервать. P.S. Извиняюсь за язык для домохозяек, но нормальное объяснение было не понято!
Если я правильно представил себе ситуацию, то чем плохо, что идет медленное рассоединение в потоке. Если существует UI, с которым взаимодействует пользователь, то мы просто эти элементы немедленно скрываем от юзера, а рассоединение спокойно идет в фоне программы в своем потоке.
protein, так и происходит. просто я пока не сделал флаг, который бы правильно работал. если быстро нажать стоп и старт, то получится, что новое соединение появится, а старое продолжит работать (поток увидит, что флаг включен, и не будет знать что его выключали). уже примерно знаю как это сделать, надо только еще хорошо подумать. похоже, что нужно создавать переменную для каждого соединения, а не использовать один и тот же участок памяти.
Механизм примитивен. Я делаю примерно так: Код (Text): var hTaskAnalyzeThread: DWORD; bStopTaskAnalyze: boolean; procedure TaskAnalyzeThread(pvoid: pointer); stdcall; begin while not bStopTaskAnalyze do begin // Тут действа Sleep(500); end; // Тут закрытие всего того, с чем работает поток ExitThread(0); end; procedure taskStartAnalyze(); var dwThreadId: DWORD; begin bStopTaskAnalyze := false; hTaskAnalyzeThread := CreateThread(nil, 0, @TaskAnalyzeThread, nil, 0, dwThreadId); end; procedure taskStopAnalyze(); begin if hTaskAnalyzeThread <> 0 then begin bStopTaskAnalyze := true; if WaitForSingleObject(hTaskAnalyzeThread, 500) = WAIT_TIMEOUT then TerminateThread(hTaskAnalyzeThread, 0); end; end;
Twister, у меня, в целом, так же сделано. отличие только в нюансах. работает отлично если пользователь жмет "Старт" , потом "Стоп". Только поток не грохается TerminateThread, а выходит сам ExitThread (внутри пропускается все что можно, если флаг сменился). Из-за этого возникает проблема: т.к. поток останавливается не мгновенно (на некоторых интернет соединениях это просто нереально), то при последующем старте, внутри потока, который еще не закончился, при проверке флага оказывается, что нужно нормально работать, а не останавливаться. У меня свой флаг на каждый сайт/страницу. Похоже нужно создавать переменную для флага на каждый поток, тогда только получится решить проблему.
Тебе нужно завести еще один флаг, который будет говорить об удачном завершении потока (не важно, сам он завершился или был убит снаружи) и не давать снова запускаться потокам, пока "флак удачного завершения" не будет установлен. Идеальным решением будет мьютекс.