Доброго дня всем!
В Дельфи я далеко не мастер, ничего профессионального не писал, однако для себя лет 5 пишу некоторые вещи. Столкнулся с проблемой при написании простенького на мой взгляд сервера.
Писалось все на Delphi 7 с использованием встроенного Indy. Простая форма, на ней Indy TCP Server и Memo для вывода логов. Вся основная обработка идет в процедуре OnExecute.
Через некоторое время после запуска сервера я обнаружил что процессор загружен на 50 процентов, еще через час на 97%. Понаблюдав логи стало понятно, что проц начинает грузиться когда подключаются несколько клиентов. Пока думаю на CoInitializeEx но что с этим делать не представляю.
По каждому подключению создается свой поток, каждый пользователь системы выполняет подключение к 1С через свой поток, я вижу в логе когда приходит команда от пользователя, в диспетчере задач открывается 1С, отрабатывает свои действия, закрывается 1С, все отлично, я бы даже понял где копать если бы речь шла о чрезмерном потреблении памяти! Но чтобы процессор так убивался на пустом месте. Еще раз хочу отметить что в какой то момент процессор переходит в режим загнанной лошади, при этом все пользователи давно отключились от сервера, а приложение продолжает нагружать проц по полной.
| Код | procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread); var i,j,f,r,o,q: integer; res, sCommand, orderinfo, orderslist, curorder: String; a,login,pass,incommand: String; c: char; v77: Olevariant; msg,onlineinfo,params:string; b:byte; len,offlineinfo:Integer; begin
with AThread.Connection do begin try i := AThread.Connection.ReadInteger(); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' '+InttoStr(i)); if ((i<1) or (i>16384)) then i:=-1; sCommand := AThread.Connection.ReadString(i); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' '+sCommand); f:=0; login:=''; pass:=''; incommand:=''; Params:=''; for j := 1 to Length(sCommand) do Begin c:=sCommand[j]; if c=' ' then f:=3; if c='#' then f:=f+1 else begin if f=0 then login:=Login+c else if f=1 then pass:=pass+c else if f=2 then incommand:=incommand+c else if f=3 then params:=params+c; end;
End; Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' LOGIN:'+Login); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' PASSWORD:'+PASS); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' COMMAND:'+incommand); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' PARAMS:'+Params);
if incommand='ONLINE' then begin CoInitializeEx (NIL, 2); v77 := createoleobject('v77s.application');
if v77.Initialize(v77.rmtrade,'/D'+BasePath+' /N'+Login+' /P'+Pass, 'NO_SPLASH_SHOW') = 0 then Begin Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' OLE ERROR'); Msg:='ERROR !!!!'; Athread.Connection.OpenWriteBuffer(); AThread.Connection.WriteInteger(length(Msg)); AThread.Connection.Write(Msg); AThread.Connection.FlushWriteBuffer(); End else begin Onlineinfo:=v77.EvalExpr('ID("'+trim(login)+'","'+trim(pass)+'")'); if Onlineinfo='1' then begin Athread.Connection.OpenWriteBuffer(); AThread.Connection.WriteInteger(length('CURRENTSTATUS '+currentstatus)); AThread.Connection.Write('CURRENTSTATUS '+currentstatus); Msg := 'STATUS 2'; Len := Length(Msg); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' Writing...'+IntToStr(Length(Msg))+' '+Msg); AThread.Connection.WriteInteger(length(Msg)); AThread.Connection.Write(Msg); AThread.Connection.FlushWriteBuffer(); end else begin Athread.Connection.OpenWriteBuffer(); Msg := 'Error '+Onlineinfo; Len := Length(Msg); Memo1.Lines.Add(DateToStr(Date())+' '+TimeToStr(Time())+' Writing...'+IntToStr(Length(Msg))+' '+Msg); AThread.Connection.WriteInteger(length(Msg)); AThread.Connection.Write(Msg); AThread.Connection.FlushWriteBuffer(); end; end; end;
try CoUnInitialize; except
end;
except on e: exception do begin
end; end; end; end;
procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread); begin Athread.Destroy; end;
|
|