मेरे पास एक डेल्फी एप्लिकेशन है जो कुछ TTimer.OnTimer ईवेंट पर 6 अज्ञात धागे उत्पन्न करता है।आवेदन पर डेल्फी में अज्ञात धागे को कैसे समाप्त करें?
यदि मैं टाइटलबार में एक्स बटन से एप्लिकेशन को बंद करता हूं तो पता $ C0000005 पर एक्सेस उल्लंघन का उपयोग किया जाता है और फास्टएमएम रिपोर्टों ने TAnonymousThread ऑब्जेक्ट्स को लीक किया है।
TThread.CreateAnonymousThread() विधि के साथ OnTimer ईवेंट में बनाए गए डेल्फी में अज्ञात धागे को मुक्त करने का सबसे अच्छा तरीका कौन सा है?
समाधान जो मेरे लिए काम किया:
गुमनाम सूत्र है जो उन्हें किया जा रहा नि: शुल्क एड पर समाप्त हो जाता है की एक आवरण बनाया गया।
type
TAnonumousThreadPool = class sealed(TObject)
strict private
FThreadList: TThreadList;
procedure TerminateRunningThreads;
procedure AnonumousThreadTerminate(Sender: TObject);
public
destructor Destroy; override; final;
procedure Start(const Procs: array of TProc);
end;
{ TAnonumousThreadPool }
procedure TAnonumousThreadPool.Start(const Procs: array of TProc);
var
T: TThread;
n: Integer;
begin
TerminateRunningThreads;
FThreadList := TThreadList.Create;
FThreadList.Duplicates := TDuplicates.dupError;
for n := Low(Procs) to High(Procs) do
begin
T := TThread.CreateAnonymousThread(Procs[n]);
TThread.NameThreadForDebugging(AnsiString('Test thread N:' + IntToStr(n) + ' TID:'), T.ThreadID);
T.OnTerminate := AnonumousThreadTerminate;
T.FreeOnTerminate := true;
FThreadList.LockList;
try
FThreadList.Add(T);
finally
FThreadList.UnlockList;
end;
T.Start;
end;
end;
procedure TAnonumousThreadPool.AnonumousThreadTerminate(Sender: TObject);
begin
FThreadList.LockList;
try
FThreadList.Remove((Sender as TThread));
finally
FThreadList.UnlockList;
end;
end;
procedure TAnonumousThreadPool.TerminateRunningThreads;
var
L: TList;
T: TThread;
begin
if not Assigned(FThreadList) then
Exit;
L := FThreadList.LockList;
try
while L.Count > 0 do
begin
T := TThread(L[0]);
T.OnTerminate := nil;
L.Remove(L[0]);
T.FreeOnTerminate := False;
T.Terminate;
T.Free;
end;
finally
FThreadList.UnlockList;
end;
FThreadList.Free;
end;
destructor TAnonumousThreadPool.Destroy;
begin
TerminateRunningThreads;
inherited;
end;
अंत यहाँ आप इसे कैसे फोन कर सकते हैं:
procedure TForm1.Button1Click(Sender: TObject);
begin
FAnonymousThreadPool.Start([ // array of procedures to execute
procedure{anonymous1}()
var
Http: THttpClient;
begin
Http := THttpClient.Create;
try
Http.CancelledCallback := function: Boolean
begin
Result := TThread.CurrentThread.CheckTerminated;
end;
Http.GetFile('http://mtgstudio.com/Screenshots/shot1.png', 'c:\1.jpg');
finally
Http.Free;
end;
end,
procedure{anonymous2}()
var
Http: THttpClient;
begin
Http := THttpClient.Create;
try
Http.CancelledCallback := function: Boolean
begin
Result := TThread.CurrentThread.CheckTerminated;
end;
Http.GetFile('http://mtgstudio.com/Screenshots/shot2.png', 'c:\2.jpg');
finally
Http.Free;
end;
end
]);
end;
कोई स्मृति लीक, उचित शटडाउन और प्रयोग करने में आसान।
'अज्ञात धागे' - ओह महान .. अब एम्बरकाडेरो ने हमें किस पर फंसाया है? –
@ मार्टिन: कुछ भी डरावना नहीं, वास्तव में। यह एक धागा है जिसका निर्माण किसी अज्ञात विधि द्वारा निर्माण समय पर प्रदान किया जाता है। यह धागे को परिभाषित करते समय बंद करने का उपयोग करने देता है। –
यह लगातार धागे को बना/नष्ट कर देता है, कुछ ऐसा जो मैंने पिछले 20 वर्षों में डेवलपर्स से बचने के लिए कहा है। फिर भी, अगर वास्तव में शुरू नहीं हुआ है, तो मैं नहीं देख सकता कि एवी क्यों होना चाहिए। –