![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Тихо умирающее приложение [D7, WinXP]
AlexNe © (2008-07-05 18:41:00)Уважаемые эксперты! Похоже я своими стараниями попал
в ситуацию из которой пока не вижу выхода.
Суть проблемы:
Имеется приложение, работающее с различными удаленными серверами через TSocketConnection, c базой данных Interbase, и с сервером реального времени, который крутится на DOS машине - соотв. через синхронный сокет TIdTCPClient.
Для работы с каждым сервером имеется отдельный поток,
причем поток сокета TIdTCPClient имеет наивысший приоритет.
Приложение работает под WinXP, работает без замечаний иногда 9 часов, иногда 3, затем элегантно, без каких либо сообщений схлопывается (а следом закрываются сервера).
Отслеживание возникающих исключений
(посылка сообщений из Application.OnException другой программе) не дало ничего - все чисто до самого схлопывания.
Запустить программу надолго под отладчиком Delphi я не имею возможности.
Безуспешные попытки найти причину доводят меня до отчаяния.
Уже вырубил на всех TSocketConnection свойство SupportCallBacks в False. Во всех Еxecute потоков защитил в
try-except все что только возможно - не помогает!
Может быть кто-нибудь сталкивался с похожей ситуацией при работе с потоками, или подскажет хотябы в какую сторону искать. Буду признателен за любые замечания
Дмитрий Белькевич (2008-07-08 12:25:00) [21]Что-то мне кажется, что решение задачи слишком усложнено. Какую проблему решает система?
Slym (2008-07-08 12:18:00) [22]AlexNe (08.07.08 11:58) [24]
Cвязь через TClientSocket
покажи как делал
AlexNe (08.07.08 11:58) [24]
Засунуть в специальный поток его проблематично
ничего проблемного:
unit Unit2;
interface
uses
Classes,Scktcomp,winsock;
type
TSockThread = class(TThread)
private
protected
procedure Execute; override;
end;
implementation
function SockWaitForData(ASocket:TSocket; ATimeout: Longint): Boolean;
var
FDSet: TFDSet;
TimeVal: TTimeVal;
begin
TimeVal.tv_sec := ATimeout div 1000;
TimeVal.tv_usec := (ATimeout mod 1000) * 1000;
FD_ZERO(FDSet);
FD_SET(ASocket, FDSet);
Result := select(0, @FDSet, nil, nil, @TimeVal) > 0;
end;
function SockReadLn(ASocket:TSocket;ATerminator:char;AMaxLineLength:integer;ATimeOut:Long int):string;
var
Buf:array[byte] of char;
SizeBuf:integer;
r,i:integer;
s:string;
begin
SizeBuf:=SizeOf(Buf);
result:='';
while SockWaitForData(ASocket,ATimeOut) do
begin
r:=recv(ASocket, Buf, SizeBuf, MSG_PEEK);
if r=SOCKET_ERROR then RaiseSocketError(WSAGetLastError, 'recv');
i:=LCharPos(@Buf,ATerminator,r);
if i<>0 then r:=i;
r:=recv(ASocket, Buf, r, 0);
if r=SOCKET_ERROR then RaiseSocketError(WSAGetLastError, 'recv');
SetString(s,Buf,r);
result:=result+s;
if i<>0 then Break;
end;
if length(result)=0 then exit;
i:=length(result)-1;
if (ATerminator=LF) and (result[i]=CR) then Dec(i);
SetLength(result,i);
end;
{ TSockThread }
procedure TSockThread.Execute;
var
Socket:TClientWinSocket;
s:string;
Code:integer;
begin
Socket:=TClientWinSocket.Create(-1);
try
Socket.ClientType:=ctBlocking;
Socket.Open('192.168.14.2','','',3128);
Socket.SendText('CONNECT hostname HTTP/1.0'#13#10);
Socket.SendText(#13#10);
s:=SockReadLn(Socket.SocketHandle);
Fetch(s,' ');
Code:=StrToIntDef(Fetch(s,' '),200);
if Code<>200 then raise Exception.CreateFmt('Bad HTTP status code: %d %s',[Code,s]);
repeat until
SockReadLn(PeerSocket.SocketHandle) = '';
...
finally
Socket.Free;
end;
end;
end.
AlexNe (2008-07-08 11:58:00) [23]to Slym
Cвязь через TClientSocket с сервером реального времени (на машине под DOS) у меня работала устойчиво только при условии установки наивысшего приоритета для всего клиентского Win приложения. Засунуть в специальный поток его проблематично. При этом, если загрузить сильно клиента, например перерисовкой интерфейса, то часть приходящих с сервера пакетов TClientSocket просто терял...
TIdTCPClient в отдельном потоке теряет ничего.
Slym (2008-07-07 05:15:00) [24]AlexNe (05.07.08 21:21) [14]
TClientSocket
Самый прямой из простых оберток на WinSock... и не только асинхронный, но синхронный см ClientType:=ctBlocking;
AlexNe (2008-07-06 11:15:00) [25]to Германн
Спасибо. Буду иметь в виду на будущее.
Германн (2008-07-06 02:34:00) [26]
> AlexNe (05.07.08 21:21) [14]
>
> Собственно проблема возникла после замены асинхронного,
> но кривого TClientSocket на не кривой, но синхронный TIdTCPClient
Есть ещё ICS. Асинхронный и не очень кривой.
AlexNe (2008-07-05 21:40:00) [27]не напиши завтраа напишу завтра, конечно...
Дмитрий Белькевич (2008-07-05 21:39:00) [28]Угу, всё в потоках замечательно работает. Сотни потоков.
AlexNe (2008-07-05 21:38:00) [29]to Дмитрий Белькевич
Спасибо, попробую. Насколько понял из хелпа это для серверов под виндой. Есть еще Interbase, но он не падал и ничего особенного не ругался. Досовский сервер пишет подробный лог, пойду его копать.
Про OnTerminate и (Sender as TThread).FatalException напиши завтра, т.к. систему забрали а работу и поэкспериментировать до утра не смогу.
Сергей М. (2008-07-05 21:30:00) [30]
> кривого TClientSocket на не кривой, но синхронный TIdTCPClient
Эдаких клоунов, зафиксировавших сей факт, - пруд пруди)
Дмитрий Белькевич (2008-07-05 21:23:00) [31]Можно еще попробовать Indy обновить до актуальных.
Дмитрий Белькевич (2008-07-05 21:21:00) [32]Даже мёртвый поток, кстати, после exception'а может OnTerminate вызвать, если его обработать, конечно. А (Sender as TThread).FatalException иногда интересные данные отдаёт.
AlexNe (2008-07-05 21:21:00) [33]Собственно проблема возникла после замены асинхронного, но кривого TClientSocket на не кривой, но синхронный TIdTCPClient для работы с сервером под DOS. Соответственно пришлось засунуть TIdTCPClient в отдельный поток, а потом и все остальные обращения к серверам рассовать по потокам. И в общем все стало работать много лучше, но в отместку этот глюк!
Дмитрий Белькевич (2008-07-05 21:17:00) [34]Удалённую отладку используй. Гарантированно Excpeption'ы покажет, да еще и потрассировать даст. Очень помогает, бывает. Особенно, когда клиент на другой стороне шарика ;)
Сергей М. (2008-07-05 21:17:00) [35]Ну тады тряси)
Авось само рассосется)
Небеса, панимаишь ..
AlexNe (2008-07-05 21:12:00) [36]to Сергей М.
на бубен, на бубен
AlexNe (2008-07-05 21:10:00) [37]to Loginov Dmitry
прошу прощения, у меня уже из-за этой проблемы фокус сбивается...
Может быть стоит. Только это ничего не даст - в програме после
каждого try except стоят WriteToLog (т.е SendMessage) , и еще
тестировалось с обработчиком Application.OnException, который как раз
записывал в лог E.Message. Так вот, за ночь ни одной записи об исключительных ситуациях и при этом два схлопывания. То есть, когда начинается разрушение, либо SendMessage не работает, либо черт знает вообще что....
Сергей М. (2008-07-05 21:03:00) [38]
> не, сервера тоже самопальные
Не, тады твоим потугам точно трындец)
Бо ты нишиша не знаешь, что . где, когда и при каких обстоятельствах у тебя чего-то там "попадает".
Ты отладчик-то пользуешь, чудо ?)
Или на бубен уповаешь ?)
Loginov Dmitry (2008-07-05 20:19:00) [39]> Или я чего-то не понял?
да фик тебя знает. Я имел ввиду следующее:
try
except
on E: Exception do
WriteToLog(E.Message);
end;
AlexNe (2008-07-05 20:03:00) [40]Просмотр системного журнала показал наличие серии ошибок Source="Application Error" Category= "None" Event=1000 но с моментами вылетов эти серии слабо кореллируют