2012-03-29 8 views
1

Ich verwende die ausgezeichnete OmniThreadLibrary-Bibliothek, um das Parsen von Quellcode zu implementieren. Das Programm muss das vorhandene Parsing beenden und das Parsing immer dann neu starten, wenn der Quellcode geändert wird.Ist dies eine korrekte Art der Verwendung von OmniThreadLibrary - beenden Sie die bestehende und erstellen Sie eine neue?

Ich mache das mit dem Code-Schnipsel unten gezeigt, ist es der richtige Weg? Muss ich noch die Terminated Eigenschaft des Threads in der ThreadedParseHtml Funktion überprüfen?

if FParserThread <> nil then 
begin 
    FParserThread.RemoveMonitor; 
    FParserThread.Terminate(500); 
end; 

FParserThread := CreateTask(ThreadedParse); 
FParserThread.SetParameter('SourceCode', Editor.Lines.Text); 
FParserThread.MonitorWith(FParserThreadMonitor); 
FParserThread.Run; 

Vielen Dank im Voraus!

Edit 1: Sorry für diese Frage der Wiedereröffnung, aber ich fand Speicherlecks, wenn FParserThread nicht von selbst vollendet, indem die Terminate Methode mit genügend Zeit Aufruf ... Irgendwelche Ideen, was könnte die Speicherlecks verursachen? Vielen Dank!

Edit 2: Lesen this blog post, konnte ich immer noch nicht, was das Problem könnte sein, da nach jedem Schritt in ThreadedParse der Code brechen, wenn Terminated ture sind ...

bearbeiten 3: Answering Robs Fragen:

  1. im OnTerminated Ereignishandler (hier nicht dargestellt), werden FParserThread auf „Null“, so von „FParser selbst abgeschlossen ist“, dann meine ich den if FParserThread <> nil then Block ist nicht Execu ted, in diesem Fall wird FParserThread beendet, weil das Parsen abgeschlossen ist.

  2. Die Logik hinter dem Code ist, dass dies ein Code-Editor ist, bei jeder Code-Bearbeitung wird ein Thread gestartet, um den Quellcode in die interne Baumdarstellung zu parsen, falls eine neue Code-Bearbeitung stattfindet aber das vorherige Parsing-Thrad wurde nicht bearbeitet, das Programm wird zuerst den vorherigen Parsing-Thread gewaltsam starten und dann einen neuen starten. Das ist vielleicht kein guter Ansatz ...

bearbeiten 4: Nach this similar SO question Lesen, änderte ich meinen Code FParserThread.Terminate ohne einen Parameter zu nennen, was bedeutet, wenn ich es richtig verstehe, diese Aussage wird nur Signal Der zu beendende Thread und innerhalb der eigentlichen Threadaufgabe habe ich die Logik angewendet, um die Threadausführung zu beenden, wenn die Eigenschaft TerminatedTrue ist.

Jetzt verdrahtet, was ist, dass mit Hilfe von Tracetool, fand ich, dass FParserThread.Terminate das OnTaskMessage Ereignis nach dem Aufruf (wo ich die Erinnerungen aufzuräumen) würde wieder nicht gefeuert werden, das ist, was die Speicherlecks verursacht ....

+0

Ok, ich denke, ich werde für das Thread-Objekt des Terminiated Flag in der Parsing-Routine überprüfen ... –

+0

Bitte fügen Sie weitere Details über die neuen im Formation. Was bedeutet es für FParserThread, "von selbst zu vervollständigen", und warum haben FParserThread überhaupt Terminate? –

+0

Rob, ich habe hinzugefügt ** Edit 3 ** Beantworten Sie Ihre Fragen, danke und Entschuldigung für die späte Antwort. –

Antwort

1

OP hier, nach der Verwendung von OmniThreadLibrary seit über 2 Jahren, ist meine Schlussfolgerung, dass die richtige Art, eine OTL-Aufgabe zu stoppen, die Stornierungs-Token ist. Codebeispiel unten.

In dem Anrufer Thread (in der Regel der Hauptthread), anrufen:

//this will tell (not kill) the thread identified by myTask to stop. 
myTask.CancellationToken.Signal; 

In der Angerufene die task.CancellationToken.IsSignaled Eigenschaft fädeln Sie müssen regelmäßig zu überprüfen, ob es wahr wird, beenden Sie die Ausführung und der Thread Kündigung wird durch das System und OTL behandelt werden:

if task.CancellationToken.IsSignaled then 
    Exit; 
3

Sie müssen die Eigenschaft Terminated in der zugehörigen Aufgabe nicht überprüfen. Sie rufen Terminate(1) an, wodurch der Thread zwangsweise beendet wird, wenn er sich nicht innerhalb des von Ihnen angegebenen 1-ms-Fensters beendet.

Es ist jedoch wirklich keine gute Idee, einen Thread gewaltsam zu beenden. Dieser Thread könnte einen Mutex oder einen kritischen Abschnitt enthalten haben, wenn Sie ihn getötet haben. Wenn Sie ihn also löschen, bleiben die Daten in einem inkonsistenten Zustand. Das könnte sich nachteilig auf Ihr gesamtes Programm auswirken.

Besser ist es, Ihren Thread zu benachrichtigen, dass Sie es beenden möchten, aber geben Sie ihm eine realistischere Frist für die Kündigung. Innerhalb des anderen Threads sollten Sie gelegentlich überprüfen, ob der Thread zum Beenden aufgefordert wurde, und sich anschließend ordnungsgemäß beenden lassen.

Wenn der Thread nicht innerhalb des angegebenen Zeitlimits endet, haben Sie größere Probleme, und das gewaltsame Töten löst sie nicht.

+0

Danke Rob, das ist die Antwort, die ich wollte und ich fand es nach ein paar Recherchen nach dieser SO Frage heraus;) –

+0

Rob, sorry, aber ich öffnete diese Frage erneut, überprüfe meine Bearbeitung, wenn du mir helfen willst des Weiteren :) –