i developed service application collecting jpeg data equipment. number of remote devices varies 1 20.
after service start creates number of threads=current number of remote devices.
every thread writing global array of records.
record:
type tdevice=record devname:string; ms:tmemorystream; end; devices:array of tdevice; cs:tcriticalsection;
threads creation
cs:=tcriticalsection.create; := 0 device_list_names.count-1 begin packs[i].ms:=tmemorystream.create; arr_ct[i]:=tclientthread.create(false,device_list_ip.strings[i], cs,packs[i].ms); arr_ct[i].freeonterminate:=false; arr_ct[i].priority:=tplower; end;
thread destroing
for := 0 length(arr_ct)-1 begin arr_ct[i].terminate; arr_ct[i].waitfor; arr_ct[i].free; end;
thread code
type tclientthread = class(tthread) private imconnected:boolean; flock:tcriticalsection; faddress:string; logpath:string; tcpcli:tidtcpclient; fms:tmemorystream; procedure createsocket; procedure getimagestreamtcp; protected procedure execute;override; public constructor create(createsuspended: boolean;const address:string; var alock:tcriticalsection; var ams:tmemorystream); end; const socketport:integer=12340; implementation uses globalvariables, superlog; constructor tclientthread.create(createsuspended: boolean;const address:string; var alock:tcriticalsection; var ams:tmemorystream); begin inherited create(createsuspended); flock:=alock; fms:=ams; faddress:=address; imconnected:=false; logpath:='e:\netview07\logs\'+faddress+'_'+ formatdatetime('dd-mm-yyyy',now)+'.log'; posttolog(logpath,'e:\netview07\logs\_'+ formatdatetime('dd-mm-yyyy',now)+'.log'); posttolog('thread '+faddress+' started',logpath); end; procedure tclientthread.createsocket; begin tcpcli:=tidtcpclient.create(nil); tcpcli.host:=faddress; tcpcli.port:=socketport; tcpcli.readtimeout:=3000; end; procedure tclientthread.getimagestreamtcp; begin try try if not imconnected begin tcpcli.connect; imconnected:=true; end; flock.enter; fms.clear; tcpcli.iohandler.writeln('grab'); tcpcli.iohandler.readstream(fms, -1); except on e:exception begin posttolog('error on receive stream('+faddress+'): ' + e.message,logpath); imconnected:=false; try tcpcli.disconnect; except on e:exception end; posttolog('imconnected=false',logpath); end; end; flock.leave; end; end; procedure tclientthread.execute; begin createsocket; while not terminated begin getimagestreamtcp; sleep(200); end; try tcpcli.disconnect; except on e:exception end; freeandnil(tcpcli); posttolog(faddress+' terminated.',logpath); end;
the problem service hangs without errors. think problem in criticalsection, because if fill code enough logging last logs entries before flock.enter.
could tell me i'm doing wrong?
i'm sorry if created duplicate of question. tried find same questions, no results.
you should use construction this
type tdevice = class protected fcriticalsection: tcriticalsection; fdevname: string; fms: tmemorystream; public constructor create; destructor destroy; override; procedure lock; procedure unlock; property devname: string read fdevname write fdevname; property ms: tmemorystream read fms write fms; end; ... constructor tdevice.create; begin inherited create; fcriticalsection := tcriticalsection.create; fms:=tmemorystream.create; end; destructor tdevice.destroy; begin freeandnil(fcriticalsection); freeandnil(fms); inherited destroy; end; procedure tdevice.lock; begin fcriticalsection.enter; end; procedure tdevice.unlock; begin fcriticalsection.leave; end;
usage
device.lock; try device.ms... // access device.unlock; end;
and pass whole device anywhere want, not stream.
then can simplify thread
constructor tclientthread.create(const address:string; adevice:tdevice); begin inherited create(false);
and handle exception in execute
procedure tclientthread.execute; begin try ... code here ... except end; end;
Comments
Post a Comment