Ich habe ein Speicherleck aufzuspüren versucht, in Jedi VCL JvHidControllerClass.pas
, die ich in der Quelle der Geschichte über diese Veränderung kam:Delphi: Sollte jemals ein Thread "nicht suspendiert" erstellt werden?
Ältere Version:
constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
inherited Create(True);
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
end;
Aktuelle Version:
constructor TJvHidDeviceReadThread.CtlCreate(const Dev: TJvHidDevice);
begin
inherited Create(False);
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
end;
Aus Erfahrung habe ich entdeckt, dass, wenn Sie einen Thread erstellen nicht suspendiert:
inherited Create(False);
dann sofort der Faden zu laufen beginnt. In diesem Fall wird versucht, auf ein Objekt zuzugreifen, die noch nicht initialisiert wird:
procedure TJvHidDeviceReadThread.Execute;
begin
while not Terminated do
begin
FillChar(Report[0], Device.Caps.InputReportByteLength, #0);
if Device.ReadFileEx(Report[0], Device.Caps.InputReportByteLength, @DummyReadCompletion) then
sofort Report
zu füllen versuchen, und rufen Sie das Objekt Device
. Problem ist, dass sie noch nicht initialisiert wurden; das sind die nächsten Linien, nachdem der Thread gestartet hat:
Device := Dev;
NumBytesRead := 0;
SetLength(Report, Dev.Caps.InputReportByteLength);
Ich weiß, dies ist eine Race-Bedingung; und die Wahrscheinlichkeit, dass ein Benutzer einen Crash in der Produktion erlebt, ist ziemlich niedrig, so dass es wahrscheinlich harmlos ist, den Renncrash zu verlassen.
Aber bin ich weg? Fehle ich etwas? Ruft:
BeginThread(nil, 0, @ThreadProc, Pointer(Self), Flags, FThreadID);
nicht starten einen Thread aus und läuft sofort? Ist das wirklich eine Race-Condition-Regression, die (absichtlich) zu JVCL hinzugefügt wurde? Gibt es ein Geheimnis über
CreateSuspended(False);
, dass es die richtige Code über macht:
CreateSuspended(True);
...
FDataThread.Resume;
?
Nach versehentlich verbrannt wurden durch
AufrufTMyThread.Create(False)
ich es in meinem Gehirn als nie korrekt eingereicht haben. Gibt es eine gültige Verwendung, um einen Thread sofort starten zu lassen (wenn Sie Werte initialisieren müssen)?
Wow !!! JVCL auf D5! Ich dachte, es wäre verstopft, nachdem ich es beendet hatte und hörte auf, D5-Kompatibilität aufrechtzuerhalten. So ein nostalgisches Gefühl ... –
@ Arioch'Das nicht zu nostalgisch sein; es ist JVCL 3.x von 2009. Und streng genommen ist es Richard Marquands ursprüngliche HidController Klasse von 2005; womit ich ein bisschen geholfen habe. Die Version, die von JVCL übernommen wurde, durchlief ein riesiges * jcl-ifying *; aber es gibt keine wirklichen Unterschiede; aber technisch verwende ich Richards Version; so kann ich den * Gebrauch-nach-frei * -Abfall beheben, den FastMM fängt. –