Вверх ↑
Этот топик читают: Гость
Ответов: 39
Рейтинг: 0
#1: 2021-02-09 19:30:18 ЛС | профиль | цитата
Добрый вечер

На Hiasm стоит такой компилятор: https://forum.hiasm.com/topic/61538
И HTTP компоненты: https://forum.hiasm.com/topic/62708

Есть такой код
Add(MultiElement,16549076,413,133)
{
@Color=11163135
}
BEGIN_SDK
Add(EditMulti,8497007,21,21)
{
EventCount=2
WorkCount=1
DataCount=5
Width=930
Height=781
link(doWork1,4805872:doCompare,[(42,27)(42,538)])
}
Add(MultiElement,13621162,357,476)
{
link(Data1,8497007:Data2,[(363,248)(34,248)])
}
BEGIN_SDK
Add(EditMulti,15391120,21,21)
{
WorkCount=1
DataCount=1
VarCount=3
Width=783
Height=494
link(doWork1,13876825:doSplit,[(53,27)(53,146)])
link(Var1,15493357:Value,[(27,361)(594,361)])
link(Var2,6376195:Value,[(34,361)(671,361)])
link(Var3,16271223:Value,[(41,361)(727,361)])
}
Add(MultiStrPart,13876825,84,140)
{
Char="@"
Point(onNotFound)
link(onSplit,11348573:doEvent1,[(149,146)])
link(Str,6472795:Var2,[])
link(onNotFound,14557135:doEvent1,[(124,153)(124,265)])
}
Add(Memory,15493357,588,175)
{
}
Add(Memory,6376195,665,175)
{
}
Add(Memory,16271223,721,175)
{
}
Add(Hub,14557135,147,259)
{
OutCount=3
link(onEvent1,7093224:doData,[])
link(onEvent2,6376195:doClear,[(392,272)(392,188)])
link(onEvent3,16271223:doClear,[(420,279)(420,188)])
}
Add(DoData,7093224,182,259)
{
link(onEventData,14513592:doEvent1,[(380,265)(380,181)])
link(Data,6472795:Var3,[(188,103)])
}
Add(GetDataEx,6472795,84,98)
{
Angle=3
link(Data,15391120:Data1,[(27,103)])
}
Add(Hub,11348573,147,119)
{
link(onEvent1,7529276:doData,[])
link(onEvent2,12759256:doSplit,[(193,132)(193,167)])
}
Add(DoData,7529276,196,119)
{
link(onEventData,14513592:doEvent2,[(390,125)(390,188)])
link(Data,13876825:Part1,[(202,107)(146,107)(146,184)(90,184)])
}
Add(Hub,14513592,553,175)
{
InCount=2
link(onEvent1,15493357:doValue,[])
}
Add(MultiStrPart,12759256,224,161)
{
Char=":"
Point(onNotFound)
link(onSplit,12812797:doEvent1,[])
link(Str,13876825:Part2,[(230,149)(164,149)(164,184)(97,184)])
}
Add(Hub,12812797,266,161)
{
link(onEvent1,15791947:doData,[(287,167)(287,146)])
link(onEvent2,9138103:doData,[(290,174)(290,188)])
}
Add(DoData,15791947,294,140)
{
link(onEventData,6376195:doValue,[(496,146)(496,181)])
link(Data,12759256:Part1,[(300,128)(265,128)(265,205)(230,205)])
}
Add(DoData,9138103,301,182)
{
link(onEventData,16271223:doValue,[(527,188)(527,181)])
link(Data,12759256:Part2,[(307,170)(272,170)(272,205)(237,205)])
}
END_SDK
Add(HTTPClient,15548230,469,630)
{
EncType=1
SendTimeout=0
RecvTimeout=0
Point(Proxy)
Point(ProxyUser)
Point(ProxyPass)
Point(onAuthProxy)
Point(doUserAgent)
Point(PostData)
Point(onStateChange)
link(URL,8497007:Data1,[(475,326)(27,326)])
link(FileName,12370419:Var3,[(482,89)])
link(onFinish,14611539:doEvent1,[])
link(Proxy,13621162:Var1,[(489,569)(363,569)])
link(ProxyUser,13621162:Var2,[(496,569)(370,569)])
link(ProxyPass,13621162:Var3,[(503,569)(377,569)])
link(PostData,7261211:Var2,[])
}
Add(Hub,14248019,294,511)
{
InCount=2
OutCount=9
link(onEvent1,14530608:doWork1,[(476,517)(476,482)])
link(onEvent3,15548230:doAbort,[(388,531)(388,650)])
link(onEvent4,13621162:doWork1,[(332,538)(332,482)])
link(onEvent5,6427523:doCompare,[(354,545)(354,524)])
link(onEvent6,7872358:doStop,[(320,552)(320,590)(275,590)(275,629)])
link(onEvent7,7872358:doStopFlag,[(320,559)(320,597)(275,597)(275,636)])
link(onEvent8,7872358:doStart,[(320,566)(320,594)(275,594)(275,622)])
link(onEvent9,13836572:doTimer,[(224,573)(224,657)])
}
Add(DoData,11849195,483,483)
{
link(onEventData,15548230:doUserAgent,[(523,489)(523,657)])
link(Data,12678903:Value,[(489,457)(552,457)])
}
Add(If_else,6427523,399,518)
{
link(onTrue,11849195:doData,[(457,524)(457,489)])
link(onFalse,331164:doData,[(457,531)(457,538)])
link(Op1,13791153:Var2,[])
link(Op2,15484997:Value,[(412,496)(433,496)])
}
Add(GetDataEx,13791153,399,427)
{
link(Data,8497007:Data3,[(405,270)(41,270)])
}
Add(DoData,331164,483,532)
{
link(Data,13791153:Var3,[(489,432)])
}
Add(Memory,15484997,427,441)
{
Default=String()
}
Add(Memory,12678903,546,399)
{
Default=String(Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0)
}
Add(Thread,7872358,287,616)
{
Delay=200
FastStop=0
BusyEvent=1
Point(doStopFlag)
link(onExec,7757213:doCompare,[])
}
Add(Hub,14611539,595,637)
{
OutCount=4
link(onEvent1,8497007:onEvent1,[(729,643)(729,27)])
link(onEvent2,13836572:doStop,[(621,650)(621,657)(226,657)(226,664)])
link(onEvent3,8853896:doEvent2,[(621,657)(621,580)(590,580)(590,503)])
}
Add(Memory,12182215,686,476)
{
Default=String(1)
}
Add(ChanelToIndex,14530608,644,476)
{
link(onIndex,12182215:doValue,[])
}
Add(If_else,4805872,63,532)
{
link(onTrue,14248019:doEvent1,[(195,538)(195,517)])
link(Op1,131268:Var1,[(69,520)])
link(Op2,408112:Var1,[(76,460)])
}
Add(Memory,4091188,112,357)
{
Default=String(1)
}
Add(Timer,13836572,231,651)
{
Interval=10000
Enable=1
AutoStop=1
link(onTimer,8853896:doEvent1,[(478,657)(478,496)])
}
Add(Hub,8853896,602,490)
{
InCount=2
link(onEvent1,14530608:doWork2,[(630,496)(630,489)])
}
Add(GetDataEx,7261211,504,609)
{
link(Data,8497007:Data4,[(510,326)(48,326)])
}
Add(If_else,2380603,112,532)
{
link(Op1,3845612:Var1,[(118,513)(268,513)(268,660)])
link(Op2,408112:Var3,[(125,460)])
}
Add(GetDataEx,408112,112,455)
{
link(Data,4091188:Value,[])
}
Add(If_else,7757213,357,616)
{
link(onTrue,15548230:doLoadString,[(429,622)(429,636)])
link(onFalse,15548230:doLoadFile,[(429,629)(429,643)])
link(Op1,12370419:Var2,[(363,318)(55,318)])
link(Op2,9439140:Value,[(370,390)(398,390)])
}
Add(GetDataEx,12370419,49,84)
{
link(Data,8497007:Data5,[])
}
Add(Memory,9439140,392,133)
{
}
Add(FormatStr,5440559,322,693)
{
DataCount=3
Mask="Переменная %1 (дб 1) Поток %2 (дб 0) ХТТП Статус %3"
link(onFString,8497007:onEvent2,[(652,699)(652,34)])
link(Str1,131268:Var2,[(328,609)(692,609)])
link(Str2,3845612:Var3,[(335,660)])
link(Str3,15548230:Status,[(342,684)(475,684)])
}
Add(Timer,7955274,266,700)
{
Interval=1
link(onTimer,5440559:doString,[(310,706)(310,699)])
}
Add(GetDataEx,131268,686,515)
{
link(Data,12182215:Value,[])
}
Add(GetDataEx,3845612,287,655)
{
link(Data,7872358:Busy,[])
}
END_SDK

Суть проблемы такова, есть программа, которая использует этот код для отправки запросов Post на адрес с периодичностью 4 сек.

Первые пару часов все идет нормально

После пары часов (и приблизительно 2+ тысяч успешно отправленных запросов) Программа перестает отправлять их. Тоесть, поток для отправки как бы запускается, но самой отправки нет.
Так же, после 2-х часов перестают открываться URL при помощи WinExec (Хотя в первые два часа все работает прекрасно)

Через минут 5 после этого программа закрывается!

Подскажите, что это может быть?

Если что, то поток я использую по совету из обсуждения Http компонентов (если его не использовать, программа подвисает немного во время отправки запроса)

P.S. Во время тестирования я отключал другие функции программы полностью и даже выводил этот кусок отдельно

Редактировалось 2 раз(а), последний 2021-02-09 19:32:39
карма: 0

0
vip
#1.1контекстная реклама от партнеров
Ответов: 165
Рейтинг: 7
#2: 2021-02-09 21:46:09 ЛС | профиль | цитата
Навскидку гдето утечка сокетов
карма: 1

0
Ответов: 4612
Рейтинг: 746
#3: 2021-02-10 12:09:28 ЛС | профиль | цитата
Никогда не используй метод Thread.doStop, а также свойство Thread.BusyEvent=Restart - это приводит к утечке ресурсов.
В частности, когда исполнение потока прерывается таким образом, пока компонент HTTPClient выполняет запрос, то в компоненте не сбрасывается "флаг занятости" (помимо не освобожденных ресурсов): при последующих вызовах компонент проверяет состояние и считает что он уже "запущен". Возможно, добавлю сообщение об ошибке для такого случая.

Для циклического повторения ставишь Thread.FastStop=False, Thread.Delay - сколько нужно паузы между запросами. Остановка - Thread.doStopFlag + HTTPClient.doAbort.

Редактировалось 5 раз(а), последний 2021-02-11 12:14:38
карма: 26

0
Ответов: 39
Рейтинг: 0
#4: 2021-02-10 13:38:33 ЛС | профиль | цитата
Netspirit писал(а):
Никогда не используй метод Thread.doStop, а также свойство Thread.BusyEvent=Restart - это приводит к утечке ресурсов.
В частности, когда исполнение потока прерывается таким образом, пока компонент HTTPClient выполняет запрос, то в компоненте не сбрасывается "флаг занятости" (помимо не освобожденных ресурсов): при последующих вызовах компонент проверяет состояние и считает что он уже "запущен". Возможно, добавлю сообщение об ошибке для такого случая.

Для циклического повторения ставишь Thread.FastStop=False, Thread.Delay - сколько нужно паузы между запросами. Остановка - Thread.doStopFlag.

Спасибо, я попробую

А есть какой то способ вручную освобождать ресурсы?
Или можно как то либо подредактировать код компонента что бы без потока работал как старый http_get?
карма: 0

0
Ответов: 4612
Рейтинг: 746
#5: 2021-02-10 14:10:53 ЛС | профиль | цитата
Там всё работает правильно. Просто запрещено грубо прерывать поток исполнения. Дай себе ответ зачем прерывать работу потока, а потом поищи другой способ решения (без прерывания).

Освобождением ресурсов занимается тот, кто их выделил, в данном случае - участвующие компоненты. В случае прерваного потока - кроме занятых ресурсов нарушается внутреннее состояние компонента: в начале работы компонент читает входящие данные, подготавливает их к работе, в процессе работы меняет временные переменные. После выполнения задачи - приводит состояние этих переменных в начальное, освобождает системные ресурсы, чего не происходит в случае обрыва исполнения.

MBO писал(а):
что бы без потока работал как старый http_get?
Вот, в HTTP_Get не делаешь остановки потока (там поток есть внутри)? Вот и здесь не делай и всё будет работать. Тупо сбрось связь с Thread.doStop и поставь Thread.BusyEvent=Ignore.

Редактировалось 3 раз(а), последний 2021-02-10 14:16:23
карма: 26

0
Ответов: 39
Рейтинг: 0
#6: 2021-02-10 20:14:18 ЛС | профиль | цитата
Netspirit писал(а):
Там всё работает правильно. Просто запрещено грубо прерывать поток исполнения. Дай себе ответ зачем прерывать работу потока, а потом поищи другой способ решения (без прерывания).

Освобождением ресурсов занимается тот, кто их выделил, в данном случае - участвующие компоненты. В случае прерваного потока - кроме занятых ресурсов нарушается внутреннее состояние компонента: в начале работы компонент читает входящие данные, подготавливает их к работе, в процессе работы меняет временные переменные. После выполнения задачи - приводит состояние этих переменных в начальное, освобождает системные ресурсы, чего не происходит в случае обрыва исполнения.

MBO писал(а):
что бы без потока работал как старый http_get?
Вот, в HTTP_Get не делаешь остановки потока (там поток есть внутри)? Вот и здесь не делай и всё будет работать. Тупо сбрось связь с Thread.doStop и поставь Thread.BusyEvent=Ignore.

Редактировалось 3 раз(а), последний 2021-02-10 14:16:23


Понял.
В общем я сделал так:

Add(MultiElement,3230401,567,266)
{
@Color=11163135
}
BEGIN_SDK
Add(EditMulti,15339671,21,21)
{
EventCount=2
WorkCount=1
DataCount=5
Width=930
Height=781
link(doWork1,7227391:doCompare,[(42,27)(42,538)])
}
Add(MultiElement,10603034,357,476)
{
link(Data1,15339671:Data2,[(363,248)(34,248)])
}
BEGIN_SDK
Add(EditMulti,3772229,21,21)
{
WorkCount=1
DataCount=1
VarCount=3
Width=783
Height=494
link(doWork1,13160684:doSplit,[(53,27)(53,146)])
link(Var1,2851825:Value,[(27,361)(594,361)])
link(Var2,3549405:Value,[(34,361)(671,361)])
link(Var3,1994398:Value,[(41,361)(727,361)])
}
Add(MultiStrPart,13160684,84,140)
{
Char="@"
Point(onNotFound)
link(onSplit,2874390:doEvent1,[(149,146)])
link(Str,4332754:Var2,[])
link(onNotFound,892182:doEvent1,[(124,153)(124,265)])
}
Add(Memory,2851825,588,175)
{
}
Add(Memory,3549405,665,175)
{
}
Add(Memory,1994398,721,175)
{
}
Add(Hub,892182,147,259)
{
OutCount=3
link(onEvent1,7826930:doData,[])
link(onEvent2,3549405:doClear,[(392,272)(392,188)])
link(onEvent3,1994398:doClear,[(420,279)(420,188)])
}
Add(DoData,7826930,182,259)
{
link(onEventData,10978073:doEvent1,[(380,265)(380,181)])
link(Data,4332754:Var3,[(188,103)])
}
Add(GetDataEx,4332754,84,98)
{
Angle=3
link(Data,3772229:Data1,[(27,103)])
}
Add(Hub,2874390,147,119)
{
link(onEvent1,6803681:doData,[])
link(onEvent2,3449222:doSplit,[(193,132)(193,167)])
}
Add(DoData,6803681,196,119)
{
link(onEventData,10978073:doEvent2,[(390,125)(390,188)])
link(Data,13160684:Part1,[(202,107)(146,107)(146,184)(90,184)])
}
Add(Hub,10978073,553,175)
{
InCount=2
link(onEvent1,2851825:doValue,[])
}
Add(MultiStrPart,3449222,224,161)
{
Char=":"
Point(onNotFound)
link(onSplit,5683787:doEvent1,[])
link(Str,13160684:Part2,[(230,149)(164,149)(164,184)(97,184)])
}
Add(Hub,5683787,266,161)
{
link(onEvent1,5785945:doData,[(287,167)(287,146)])
link(onEvent2,10110114:doData,[(290,174)(290,188)])
}
Add(DoData,5785945,294,140)
{
link(onEventData,3549405:doValue,[(496,146)(496,181)])
link(Data,3449222:Part1,[(300,128)(265,128)(265,205)(230,205)])
}
Add(DoData,10110114,301,182)
{
link(onEventData,1994398:doValue,[(527,188)(527,181)])
link(Data,3449222:Part2,[(307,170)(272,170)(272,205)(237,205)])
}
END_SDK
Add(HTTPClient,15281445,469,630)
{
Method=1
EncType=1
SendTimeout=0
RecvTimeout=0
Point(Proxy)
Point(ProxyUser)
Point(ProxyPass)
Point(onAuthProxy)
Point(doUserAgent)
Point(PostData)
Point(onStateChange)
link(URL,15339671:Data1,[(475,326)(27,326)])
link(FileName,7399373:Var3,[(482,89)])
link(onFinish,11854635:doEvent1,[])
link(Proxy,10603034:Var1,[(489,569)(363,569)])
link(ProxyUser,10603034:Var2,[(496,569)(370,569)])
link(ProxyPass,10603034:Var3,[(503,569)(377,569)])
link(PostData,12861955:Var2,[])
}
Add(Hub,3606552,294,511)
{
InCount=2
OutCount=9
link(onEvent1,2566564:doWork1,[(476,517)(476,482)])
link(onEvent3,15281445:doAbort,[(371,531)(371,678)(458,678)(458,650)])
link(onEvent4,10603034:doWork1,[(332,538)(332,482)])
link(onEvent5,12973578:doCompare,[(354,545)(354,524)])
link(onEvent8,8951318:doStart,[(320,566)(320,594)(275,594)(275,622)])
link(onEvent9,9202351:doTimer,[(224,573)(224,657)])
}
Add(DoData,2126026,483,483)
{
link(onEventData,15281445:doUserAgent,[(523,489)(523,657)])
link(Data,3545356:Value,[(489,457)(552,457)])
}
Add(If_else,12973578,399,518)
{
link(onTrue,2126026:doData,[(457,524)(457,489)])
link(onFalse,13679769:doData,[(457,531)(457,538)])
link(Op1,5964060:Var2,[])
link(Op2,2001601:Value,[(412,496)(433,496)])
}
Add(GetDataEx,5964060,399,427)
{
link(Data,15339671:Data3,[(405,270)(41,270)])
}
Add(DoData,13679769,483,532)
{
link(Data,5964060:Var3,[(489,432)])
}
Add(Memory,2001601,427,441)
{
Default=String()
}
Add(Memory,3545356,546,399)
{
Default=String(Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0)
}
Add(Thread,8951318,287,616)
{
Delay=200
FastStop=0
Point(doStopFlag)
link(onExec,6565431:doCompare,[])
}
Add(Hub,11854635,595,637)
{
OutCount=4
link(onEvent1,15339671:onEvent1,[(729,643)(729,27)])
link(onEvent2,9202351:doStop,[(621,650)(621,657)(226,657)(226,664)])
link(onEvent3,16554511:doEvent2,[(621,657)(621,580)(590,580)(590,503)])
}
Add(Memory,14893065,686,476)
{
Default=String(1)
}
Add(ChanelToIndex,2566564,644,476)
{
link(onIndex,14893065:doValue,[])
}
Add(If_else,7227391,63,532)
{
link(onTrue,11698479:doCompare,[])
link(Op1,15281892:Var1,[(69,520)])
link(Op2,3219965:Var1,[(76,460)])
}
Add(Memory,9893737,112,357)
{
Default=String(1)
}
Add(Timer,9202351,231,651)
{
Interval=10000
Enable=1
AutoStop=1
link(onTimer,16554511:doEvent1,[(478,657)(478,496)])
}
Add(Hub,16554511,602,490)
{
InCount=2
link(onEvent1,2566564:doWork2,[(630,496)(630,489)])
}
Add(GetDataEx,12861955,504,609)
{
link(Data,15339671:Data4,[(510,326)(48,326)])
}
Add(If_else,11698479,112,532)
{
link(onFalse,3606552:doEvent1,[(219,545)(219,517)])
link(Op1,16153412:Var1,[(118,513)(268,513)(268,660)])
link(Op2,3219965:Var3,[(125,460)])
}
Add(GetDataEx,3219965,112,455)
{
link(Data,9893737:Value,[])
}
Add(If_else,6565431,357,616)
{
link(onTrue,15281445:doLoadString,[(429,622)(429,636)])
link(onFalse,15281445:doLoadFile,[(429,629)(429,643)])
link(Op1,7399373:Var2,[(363,318)(55,318)])
link(Op2,14123805:Value,[(370,390)(398,390)])
}
Add(GetDataEx,7399373,49,84)
{
link(Data,15339671:Data5,[])
}
Add(Memory,14123805,392,133)
{
}
Add(FormatStr,5964964,322,693)
{
DataCount=3
Mask="Переменная %1 (дб 1) Поток %2 (дб 0) ХТТП Статус %3"
link(onFString,15339671:onEvent2,[(652,699)(652,34)])
link(Str1,15281892:Var2,[(328,609)(692,609)])
link(Str2,16153412:Var3,[(335,660)])
link(Str3,15281445:Status,[(342,684)(475,684)])
}
Add(Timer,7780620,266,700)
{
Interval=1
link(onTimer,5964964:doString,[(310,706)(310,699)])
}
Add(GetDataEx,15281892,686,515)
{
link(Data,14893065:Value,[])
}
Add(GetDataEx,16153412,287,655)
{
link(Data,8951318:Busy,[])
}
END_SDK


верно?

Или http запрос тоже лучше не прерывать?
карма: 0

0
Ответов: 2059
Рейтинг: 131
#7: 2021-02-10 21:08:37 ЛС | профиль | цитата
MBO
Что за необходимость полностью копировать предыдущий пост?
Мы и так его можем прочитать без дублирования.
Это бескультурье, или лень выделить важные слова и мысли?
Это неуважение к оппоненту.

Редактировалось 1 раз(а), последний 2021-02-10 21:11:05
карма: 6

0
Ответов: 4612
Рейтинг: 746
#8: 2021-02-11 12:16:04 ЛС | профиль | цитата
MBO писал(а):
Или http запрос тоже лучше не прерывать?
Ну, такая возможность предусмотрена (метод doAbort), поэтому если не будет работать - сообщай.

Более важный вопрос: а зачем перед тем как запустить новый запрос, делать doAbort предыдущего (на одном и том же Hub)? То-есть, предполагается что если запрос не был завершен перед поступлением нового - то "ну его нафиг, поезд ушел, всё убиваем-отменяем и начинаем следующий запрос"? А если временно сеть просела или сервер немного дольше отвечал - результаты запроса неинтересны? Тогда для таких случаев есть свойства таймаутов.

А правильный способ беспрерывного (циклического) посылания запросов я выше указал. На каждой итерации Thread.onExec выбирается из списка/генерируется следующий запрос и выполняется. Можно применить и Thread.FastStop=True (однократное срабатывание onExec), но на выходе из потока ставится перебор списка (если таковой есть) с параметрами запроса, которые последовательно подаются на HTTPClient.

Кстати, если сделать doAbort, а потом сразу же попытаться запустить новый поток - то предыдущий может ещё не успеть завершиться и новый не будет запущен (при Thread.BusyEvent=Ignore). Вероятно, поэтому было применено Thread.BusyEvent=Restart. Что подтверждает неверную логику.

Редактировалось 3 раз(а), последний 2021-02-11 12:23:00
карма: 26

0
Ответов: 39
Рейтинг: 0
#9: 2021-02-11 15:25:47 ЛС | профиль | цитата
Netspirit писал(а):
MBO писал(а):
Более важный вопрос: а зачем перед тем как запустить новый запрос, делать doAbort предыдущего (на одном и том же Hub)? То-есть, предполагается что если запрос не был завершен перед поступлением нового - то "ну его нафиг, поезд ушел, всё убиваем-отменяем и начинаем следующий запрос"? А если временно сеть просела или сервер немного дольше отвечал - результаты запроса неинтересны? Тогда для таких случаев есть свойства таймаутов.

Ну впринципе, да)
Если старый не дошел на него уже лучше забить

А может быть можно добавить в компонент хттп клиента точку isBusy?
Или может быть можно дописать код так, чтобы сам хттп клиент не забирал управление программой (и она не подвисала) а работал как старый HTTP_GET в отдельном потоке

Или не могли Вы привести пример отправки http запроса как Вы считаете правильным?

Может это я что-то не так делаю

Кстати немного изменил схему убрав прерывание предидущего потока - вроди стало получше, впервый раз программа вылетела через 4 часа
карма: 0

0
Ответов: 4612
Рейтинг: 746
#10: 2021-02-11 16:39:09 ЛС | профиль | цитата
MBO писал(а):
Если старый не дошел на него уже лучше забить
Для того чтобы "забить", надо дождаться результата - "дошел" или нет. Ты же, не дожидаясь результата убиваешь исполнение. Успел запрос к этому моменту отработать - ему повезло, а нет - так это его проблемы. Это - критическая проблема логики, с которой ты и начал эту тему: ты неконтролированно множишь использование ресурсов (например, открытые сетевые соединения), не дожидаясь освобождения предыдущих. А при реализации этой логики путем убивания потока исполнения - освобождение и не светит.

MBO писал(а):
а работал как старый HTTP_Get в отдельном потоке
Это абсолютно идентично обеспечивается компонентом Thread+HTTPClient. Нужна точка "Busy"? Она есть у компонента Thread и будет выполнять ровно ту же функцию. При этом помня что "никогда не используй метод Thread.doStop, а также свойство Thread.BusyEvent=Restart"

MBO писал(а):
Может это я что-то не так делаю
Перестань подавать данные для следующих запросов "извне" параллельного потока Thread. Из того места, в котором понадобилась точка "Busy". Не нужно знать закончил ли поток выполнять все запросы: ты изначально ему должен задать условия, когда он должен закончить работу. И быть уверенным что он закончится именно при наступлении тех условий. Например, по окончанию перебора списка запросов.

1) Подготовь все необходимые данные для запросов. Запусти Thread (Thread.FastStop=False). По Thread.onExec взял следующие по списку данные, подал на HTTPClient, выполнил запрос. Пока запрос будет выполняться, Thread.onExec не начнет выбирать следующие данные и выполнять следующий запрос.

2) Подготовь данные. Запусти Thread (Thread.FastStop=True). По Thread.onExec поставь ArrayEnum, перебирающий список запросов. На выходе ArrayEnum стоит HTTPClient, выполняющий запросы.

Ничего не надо прерывать - каждый новый запрос выполняется только после завершения предыдущего. Хочешь чтобы меньше времени тратилось на ожидание неотвечающего сервера - уменьши таймауты HTTPClient. Хочешь интервал между запросами? Измени Thread.Delay (при Thread.FastStop=False). Хочешь остановить работу? Thread.doStopFlag + HTTPClient.doAbort + ArrayEnum.doStop. Хочешь узнать когда все запросы будут выполнены? Событие ArrayEnum.onEndEnum или вторая точка хаба на выходе с Thread.onExec (первая точка - на выполнение запросов).

Редактировалось 3 раз(а), последний 2021-02-11 16:48:33
карма: 26

0
Ответов: 39
Рейтинг: 0
#11: 2021-02-11 17:22:50 ЛС | профиль | цитата
понял, спасибо
А есть ли какой-то способ размножать потоки?

Типо первый начал выполнение, потом (если должен начаться второй) он начинается отдельно, если первый не завершился. Но первый при этом не прерывается, а ждет ответа от сервера

--- Добавлено в 2021-02-11 17:26:43

Вобще, я останавливаю поток и запрос для того, что бы можно было обработать предыдущий ответ в случае ошибки и отправить еще один (уже другой) запрос

--- Добавлено в 2021-02-11 17:28:07

Можно ли вообще как-то посмотреть занятые и освобожденные программой ресурсы? А управлять ими средствами HiAsm?

Редактировалось 2 раз(а), последний 2021-02-11 17:28:07
карма: 0

0
Ответов: 4612
Рейтинг: 746
#12: 2021-02-11 17:41:05 ЛС | профиль | цитата
MBO писал(а):
А есть ли какой-то способ размножать потоки?
Это можно реализовать динамическим контейнером, когда в каждом экземпляре схемы находится поток, выполняющий работу и HTTPClient. Логика такая: подготавливаются данные для каждого потока. Создаётся новый экземпляр динамического контейнера, в него подаются соответствующие данные. Когда все экземпляры подготовлены, потоки каждого экземпляра запускаются на выполнение. Но это все равно может быть не тем, что ожидается, там могут быть различные проблемы.
Подходящая реализация - запуск фиксированного количества потоков, каждому из которых дается часть общего списка запросов и он свою часть выполняет последовательно, как описано выше для одного.

MBO писал(а):
Но первый при этом не прерывается, а ждет ответа от сервера
Опять же, количество потоков в ситеме ограничено, большое количество вызывает проблемы. Запускаем новый, не дождавшись предыдущего - получаем постоянное увеличение потребления ресурсов (параллельных потоков, сетевых соединений и т.д.).

MBO писал(а):
Вобще, я останавливаю поток и запрос для того, что бы можно было обработать предыдущий ответ в случае ошибки и отправить еще один (уже другой) запрос
Для этого у компонента HTTPClient есть событие onError или точка StatusCode. По завершении запроса обрабатываешь результат, если произошла ошибка - ставишь ещё один HTTPClient для выполнения другого запроса в случае ошибки. Все это выполняется в том же потоке, который делал первый запрос.
Следует отличать:
- "в случае ошибки выполнить другой запрос" - это как написал
- "в случае ошибки перейти к следующему запросу" - это решается выше описанным перебором списка запросов.

Остается вопрос: в случае ошибки выполнить другой запрос, а если ошибки не произошло - что надо сделать? А если и этот другой запрос выполнился с ошибкой - что надо сделать? А если успешен?

MBO писал(а):
Можно ли вообще как-то посмотреть занятые и освобожденные программой ресурсы? А управлять ими средствами HiAsm?
В контексте обсуждаемой задачи - нет. Потому что управлением занимается компонент, и утечка происходит по причине ущербной логики (а точнее - только по причине принудительной остановки потока исполнения). Убираешь обрыв потока - убираешь одну из двух проблем: утечку ресурсов. И остаешься один на один с проблемой логики: как выполнить свою задачу, дожидаясь завершения предыдущего запроса.
Любое "внешнее управление ресурсами" при той же логике будет приводить к тем же результатам.

И это не проблема HTTPClient. В HTTP_Get происходит ровно то же самое, просто ты не заглядывал внутрь. А там не стоит проверки на повторный запуск. Запустил первый запрос - он запустился в параллельном потоке и ожидает ответа сервера. А ты в это время запускаешь второй запрос. Проверки в компоненте нет, ты думаешь "вау, второй запрос пошел" (или думаешь компонент там внутри сам знает что ему надо отменить предыдущий?). И ждешь результатов второго запроса. А в этот момент там внутри проснулся первый запрос, о котором компонент уже забыл, и выдал событие onDownload. А ты думаешь что это событие с результатом второго запроса. А если пять запросов одновременно выполнить - какое по порядку событие данные какого по порядку запроса будет выдавать?

Редактировалось 10 раз(а), последний 2021-02-12 11:52:31
карма: 26

0
Ответов: 39
Рейтинг: 0
#13: 2021-02-11 18:44:00 ЛС | профиль | цитата
Понял, попробую ещё реализовать динамическим контейнером

А onerror или при изменении статус кода не прокатит. У меня ошибка передаётся в ответе

Спасибо за подсказки

--- Добавлено в 2021-02-11 19:32:55

Ну не, я уже убрал прерывание потока "насильно", но всеравно программа вырубается через 2+часа

Посмотрите, пожалуйста, может я что-то не так делаю?


Make(delphi)
ver(4.05 build 186)
Add(MainForm,2953706,21,105)
{
Width=527
Height=413
link(onCreate,11422444:doString,[(114,125)(114,97)])
}
Add(Memo,14828705,868,182)
{
Top=50
Width=511
Height=324
Align=5
AddType=1
link(onChange,801416:doLength,[])
}
Add(Button,12132440,350,322)
{
Width=511
Height=50
Align=2
link(onClick,8928539:doShellExec,[(404,328)(404,335)])
}
Add(WinExec,8928539,427,322)
{
}
Add(MultiElement,9318530,343,245)
{
@Color=11163135
link(onEvent1,5289262:doString,[])
link(Data1,12917168:Value,[(349,89)(384,89)])
link(Data2,3254399:Value,[(356,149)(440,149)])
}
BEGIN_SDK
Add(EditMulti,3634868,21,21)
{
EventCount=1
WorkCount=1
DataCount=5
Width=930
Height=781
link(doWork1,12666540:doCompare,[(42,27)(42,538)])
}
Add(MultiElement,15921226,357,476)
{
link(Data1,3634868:Data2,[(363,248)(34,248)])
}
BEGIN_SDK
Add(EditMulti,14911298,21,21)
{
WorkCount=1
DataCount=1
VarCount=3
Width=783
Height=494
link(doWork1,2327038:doSplit,[(53,27)(53,146)])
link(Var1,1160941:Value,[(27,361)(594,361)])
link(Var2,2055145:Value,[(34,361)(671,361)])
link(Var3,10482298:Value,[(41,361)(727,361)])
}
Add(MultiStrPart,2327038,84,140)
{
Char="@"
Point(onNotFound)
link(onSplit,7271578:doEvent1,[(149,146)])
link(Str,15582719:Var2,[])
link(onNotFound,12142469:doEvent1,[(124,153)(124,265)])
}
Add(Memory,1160941,588,175)
{
}
Add(Memory,2055145,665,175)
{
}
Add(Memory,10482298,721,175)
{
}
Add(Hub,12142469,147,259)
{
OutCount=3
link(onEvent1,7517633:doData,[])
link(onEvent2,2055145:doClear,[(392,272)(392,188)])
link(onEvent3,10482298:doClear,[(420,279)(420,188)])
}
Add(DoData,7517633,182,259)
{
link(onEventData,14285636:doEvent1,[(380,265)(380,181)])
link(Data,15582719:Var3,[(188,103)])
}
Add(GetDataEx,15582719,84,98)
{
Angle=3
link(Data,14911298:Data1,[(27,103)])
}
Add(Hub,7271578,147,119)
{
link(onEvent1,12435606:doData,[])
link(onEvent2,12544637:doSplit,[(193,132)(193,167)])
}
Add(DoData,12435606,196,119)
{
link(onEventData,14285636:doEvent2,[(390,125)(390,188)])
link(Data,2327038:Part1,[(202,107)(146,107)(146,184)(90,184)])
}
Add(Hub,14285636,553,175)
{
InCount=2
link(onEvent1,1160941:doValue,[])
}
Add(MultiStrPart,12544637,224,161)
{
Char=":"
Point(onNotFound)
link(onSplit,10835903:doEvent1,[])
link(Str,2327038:Part2,[(230,149)(164,149)(164,184)(97,184)])
}
Add(Hub,10835903,266,161)
{
link(onEvent1,15683516:doData,[(287,167)(287,146)])
link(onEvent2,3122225:doData,[(290,174)(290,188)])
}
Add(DoData,15683516,294,140)
{
link(onEventData,2055145:doValue,[(496,146)(496,181)])
link(Data,12544637:Part1,[(300,128)(265,128)(265,205)(230,205)])
}
Add(DoData,3122225,301,182)
{
link(onEventData,10482298:doValue,[(527,188)(527,181)])
link(Data,12544637:Part2,[(307,170)(272,170)(272,205)(237,205)])
}
END_SDK
Add(HTTPClient,13486350,497,686)
{
Method=1
EncType=1
ConnectTimeout=15000
SendTimeout=0
RecvTimeout=0
Point(Proxy)
Point(ProxyUser)
Point(ProxyPass)
Point(onAuthProxy)
Point(doUserAgent)
Point(PostData)
Point(onStateChange)
Point(doCustomMethod)
link(URL,3634868:Data1,[(503,326)(27,326)])
link(FileName,7399373:Var3,[(510,89)])
link(onFinish,7205917:doEvent1,[])
link(Proxy,15921226:Var1,[(517,569)(363,569)])
link(ProxyUser,15921226:Var2,[(524,569)(370,569)])
link(ProxyPass,15921226:Var3,[(531,569)(377,569)])
link(PostData,6535530:Var2,[])
}
Add(Hub,9914947,294,511)
{
InCount=2
OutCount=9
link(onEvent1,1447053:doWork1,[(476,517)(476,482)])
link(onEvent4,15921226:doWork1,[(332,538)(332,482)])
link(onEvent5,3577732:doCompare,[(354,545)(354,524)])
link(onEvent8,10903385:doStart,[(320,566)(320,594)(275,594)(275,678)])
link(onEvent9,14884823:doTimer,[(224,573)(224,713)])
}
Add(DoData,12209347,483,483)
{
link(onEventData,13486350:doUserAgent,[(522,489)(522,713)])
link(Data,7176825:Value,[(489,457)(552,457)])
}
Add(If_else,3577732,399,518)
{
link(onTrue,12209347:doData,[(457,524)(457,489)])
link(onFalse,13679300:doData,[(457,531)(457,538)])
link(Op1,14767262:Var2,[])
link(Op2,12767415:Value,[(412,496)(433,496)])
}
Add(GetDataEx,14767262,399,427)
{
link(Data,3634868:Data3,[(405,270)(41,270)])
}
Add(DoData,13679300,483,532)
{
link(Data,14767262:Var3,[(489,432)])
}
Add(Memory,12767415,427,441)
{
Default=String()
}
Add(Memory,7176825,546,399)
{
Default=String(Mozilla/5.0 (Windows NT 5.1; rv:52.0) Gecko/20100101 Firefox/52.0)
}
Add(Thread,10903385,315,672)
{
Delay=200
FastStop=0
link(onExec,6565431:doCompare,[])
}
Add(Hub,7205917,623,693)
{
OutCount=4
link(onEvent1,3634868:onEvent1,[(729,699)(729,27)])
link(onEvent2,14884823:doStop,[(649,706)(649,713)(254,713)(254,720)])
link(onEvent3,10386299:doEvent2,[(642,713)(642,580)(590,580)(590,503)])
}
Add(Memory,1032677,686,476)
{
Default=String(1)
}
Add(ChanelToIndex,1447053,644,476)
{
link(onIndex,1032677:doValue,[])
}
Add(If_else,12666540,63,532)
{
link(onTrue,2892296:doCompare,[])
link(Op1,15281892:Var1,[(69,520)])
link(Op2,9146203:Var1,[(76,460)])
}
Add(Memory,3176811,112,357)
{
Default=String(1)
}
Add(Timer,14884823,259,707)
{
Interval=15000
Enable=1
AutoStop=1
link(onTimer,10386299:doEvent1,[(478,713)(478,496)])
}
Add(Hub,10386299,602,490)
{
InCount=2
link(onEvent1,1447053:doWork2,[(630,496)(630,489)])
}
Add(GetDataEx,13492034,504,609)
{
link(Data,3634868:Data4,[(510,326)(48,326)])
}
Add(If_else,2892296,112,532)
{
link(onFalse,9914947:doEvent1,[(219,545)(219,517)])
link(Op1,16153412:Var1,[(118,513)(268,513)(268,716)])
link(Op2,9146203:Var3,[(125,460)])
}
Add(GetDataEx,9146203,112,455)
{
link(Data,3176811:Value,[])
}
Add(If_else,6565431,385,672)
{
link(onTrue,13486350:doLoadString,[(457,678)(457,692)])
link(onFalse,13486350:doLoadFile,[(457,685)(457,699)])
link(Op1,7399373:Var2,[(391,318)(55,318)])
link(Op2,14123805:Value,[])
}
Add(GetDataEx,7399373,49,84)
{
link(Data,3634868:Data5,[])
}
Add(Memory,14123805,392,133)
{
}
Add(GetDataEx,15281892,686,515)
{
link(Data,1032677:Value,[])
}
Add(GetDataEx,16153412,315,711)
{
link(Data,10903385:Busy,[])
}
Add(GetDataEx,6535530,532,647)
{
Angle=3
link(Data,13492034:Var2,[(510,652)])
}
END_SDK
Add(Timer,14462657,133,161)
{
Interval=4000
link(onTimer,6286219:doEvent1,[])
}
Add(Memory,12917168,378,28)
{
Default=String(https://api.vk.com/method/wall.get.xml)
}
Add(Memory,3254399,434,21)
{
Default=String(193.56.188.118:8000@vTH1sM:Cqkp9P)
}
Add(FormatStr,15584895,301,175)
{
Mask="Пробуем отправить запрос..."
link(onFString,15308901:doEvent1,[(439,181)(439,202)])
}
Add(MultiElement,13613827,917,294)
{
link(Data1,5871902:Value,[(923,184)(825,184)])
}
BEGIN_SDK
Add(EditMulti,16152815,21,21)
{
WorkCount=1
DataCount=1
Width=769
Height=508
link(doWork1,16549455:doValue,[(35,27)])
}
Add(FormatStr,6743866,175,217)
{
DataCount=1
Mask="%1.txt"
Point(FString)
link(onFString,13380617:doLoad,[(265,223)(265,237)])
link(Str1,16152815:Data1,[(181,119)(27,119)])
}
Add(Hub,11787960,77,77)
{
OutCount=6
link(onEvent3,6743866:doString,[(133,97)(133,223)])
link(onEvent4,4083985:doString,[(126,104)(126,279)])
link(onEvent5,13380617:doSave,[(207,111)(207,230)])
link(onEvent6,13380617:doClear,[(207,118)(207,202)])
}
Add(GetDataEx,5696236,203,81)
{
}
Add(Time,2036820,224,112)
{
Format="Y_M_D"
}
Add(StrList,13380617,322,189)
{
Point(doAppend)
Point(doAppendText)
Point(doLoad)
Point(doSave)
link(Str,4083985:FString,[(328,177)(248,177)(248,317)(167,317)])
link(FileName,6743866:FString,[(335,177)(258,177)(258,261)(181,261)])
}
Add(FormatStr,4083985,161,273)
{
Mask="%1"
Point(FString)
link(onFString,13380617:doAppendText,[(257,279)(257,230)])
link(Str1,16549455:Value,[(167,191)(41,191)])
}
Add(Memory,16549455,35,63)
{
Default=String()
link(onData,11787960:doEvent1,[(72,69)(72,83)])
}
END_SDK
Add(Hub,6286219,231,161)
{
link(onEvent1,15584895:doString,[(273,167)(273,181)])
link(onEvent2,9318530:doWork1,[(294,174)(294,251)])
}
Add(Hub,15777583,819,196)
{
InCount=2
link(onEvent1,14828705:doAdd,[(851,202)(851,188)])
link(onEvent2,13613827:doWork1,[(875,209)(875,300)])
}
Add(Length,801416,931,182)
{
link(onLength,1062812:doCompare,[])
link(Str,3998827:Var3,[(937,170)(905,170)(905,226)])
}
Add(If_else,1062812,980,182)
{
Type=2
link(onTrue,13856670:doCopy,[])
link(Op1,801416:Result,[(986,170)(962,170)(962,226)(937,226)])
link(Op2,588345:Var2,[])
}
Add(Memory,15621462,973,35)
{
Default=String(5000)
}
Add(Copy,13856670,1043,182)
{
link(onCopy,14828705:doText,[(1087,188)(1087,198)(856,198)(856,209)])
link(Str,3998827:Var1,[(1049,170)(865,170)(865,226)])
link(Position,15120981:Value,[(1056,156)(1049,156)])
link(Count,588345:Var3,[(1063,152)])
}
Add(GetDataEx,588345,987,147)
{
link(Data,15621462:Value,[(993,124)(979,124)])
}
Add(Memory,15120981,1043,98)
{
Default=String(0)
}
Add(GetDataEx,3998827,868,221)
{
link(Data,14828705:Text,[])
}
Add(Memory,5871902,819,42)
{
Default=String(testlog.txt)
}
Add(FormatStr,5289262,392,245)
{
Mask="Ответ получен...\r\n%1"
link(onFString,15308901:doEvent2,[(436,251)(436,209)])
}
Add(Hub,15308901,448,196)
{
InCount=3
link(onEvent1,4720990:doValue,[])
}
Add(FormatStr,11639986,560,196)
{
Mask="==========\r\n%1 > %2\r\n\r\n"
link(onFString,15777583:doEvent1,[])
link(Str1,176083:FormatTime,[(566,174)(587,174)])
link(Str2,4720990:Value,[(573,184)(535,184)(535,240)(496,240)])
}
Add(Time,176083,581,119)
{
Format="[h:m:s]"
}
Add(Memory,4720990,490,196)
{
Default=String()
link(onData,11639986:doString,[])
}
Add(FormatStr,11422444,175,91)
{
Mask="START PROG"
link(onFString,15308901:doEvent3,[(327,97)(327,216)])
}


Редактировалось 1 раз(а), последний 2021-02-11 19:32:55
карма: 0

0
Ответов: 4612
Рейтинг: 746
#14: 2021-02-12 12:16:03 ЛС | профиль | цитата
MBO писал(а):
У меня ошибка передаётся в ответе
Ну, так проверяй содержимое ответа по onFinish и реагируй как надо.
MBO писал(а):
Посмотрите, пожалуйста, может я что-то не так делаю?
Таймеры не нужны.
1) Удаляешь Timer и Thread из контейнера
2) Вместо таймера в главной форме ставишь Thread с FastStop=False и Delay=4000
3) Делаешь Thread.doStart - получаешь тот же "таймер" в параллельном потоке. Или вместо Timer ставишь MMTimer - и вообще компонента Thread не надо: запросы и так будут выполняться в параллельном потоке.

MBO писал(а):
но всеравно программа вырубается через 2+часа
Если результаты работы параллельного потока (Thread, MMTimer, WinExec.onConsoleResult и др.) выводятся в визуальные компоненты (Memo) - такие обращения надо защищать с помощью компонента Synchronize. Поставь Synchronize на выходе из контейнера.

Редактировалось 1 раз(а), последний 2021-02-12 17:49:38
карма: 26

1
Голосовали:MBO
Ответов: 39
Рейтинг: 0
#15: 2021-02-12 17:37:38 ЛС | профиль | цитата
Спасибо за совет
Вроди замена таймера и синхронизация помогли

я сделал две программы (для разных способов) и обе работают пока что без перебоя (4+ часа)

еще такой вопрос, а возможно ли то, что одна и та же программа (до изменений) на одном компе вылетает через 2+ часа, а на другом - нет? И от чего это зависит
карма: 0

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)