alogrep 0 Posted January 14, 2024 HI In the following code I put 2 breakpoints at the beginning of Thread.Create and of Thread.Destroy. I noticed that in all cases except one the sequence Crate/Destroy is executed in the correct order. But in one case, Destroy is called twice in a row. Does anybody have an idea as to why? Constructor SendThread.Create(afmods:modslist; atablename: string;uniquenumber: int64;asavedir,adbase: string); begin inherited create(false); FreeOnTerminate:=true; fmods:=afmods; tablename:=atablename; uniq:=uniquenumber; dbase:=adbase; savedir:=asavedir; sstream:=TStringstream.create; end; Destructor SendThread.Destroy; begin sstream.free; inherited Destroy; end; procedure SendThread.Execute; var s,last1: string; l,i,n,modindex: integer; done: boolean; t: textfile; begin if length(fmods)<=0 then exit; modindex:=getmodindex(inttostr(uniq),fmods); with fmods[modindex] do begin // s:=format('%-11s',[fmods[high(fmods)].val]); // sStream.writestring(s); for l:=0 to high(mods) do begin sstream.writestring(format('%4s',[inttostr(mods[l].fieldpos)])); sstream.writestring(format('%10d',[length(mods[l].val)])); sStream.writestring(mods[l].val); END; mods:=Nil; end; sStream.position:=0; s:=Format('%.*d',[13, uniq]); s:= savedir+'\'+s+'$'+trim(copy(dbase,Lastdelimiter('\',dbase)+1,10))+'-'+tablename+'.db'; sStream.savetofile(s); last1:=inttostr(Lastuniquenumber); sStream.clear; sstream.writestring(format('%4s',['0'])); sstream.writestring(format('%10d',[length(last1)])); sStream.writestring(last1); s:=Format('%.*d',[13, uniq]); s:= savedir+'\'+s+'$pos-'+tablename+'.db'; sStream.savetofile(s); end; Share this post Link to post
Der schöne Günther 323 Posted January 14, 2024 In all cases? What are those cases? Can you provide a minimal example (that actually compiles) with all your test cases? Share this post Link to post
Remy Lebeau 1472 Posted January 14, 2024 Why is the code creating the TStringStream object in the constructor and destroying it in the destructor, instead of just using it locally inside of Execute()? Do other threads need access to the TStringStream? If not, then it doesn't need to be a class member. Share this post Link to post
aehimself 402 Posted January 14, 2024 If you have FreeOnTerminate := True and you call .Free, you can have 2 destructors but one will raise an AV as you are .Free.ing the StringStream instead of FreeAndNil. Share this post Link to post
David Heffernan 2366 Posted January 14, 2024 Defect in your code, but in the code you didn't show. Share this post Link to post
Brian Evans 111 Posted January 15, 2024 Look at and compare the call stacks between the multiple hits of the breakpoint. 1 Share this post Link to post