2016-09-02 4 views
2

Ich muss einen TCP-Server und Client mit persistenten Verbindungen mit Indy und Delphi XE2 entwickeln. Fast alles läuft gut.Delphi TIdTcpServer Force Stop IdSync nach SomeTimeOut

Dieser Dienst ist ein kritischer Dienst, deshalb muss ich etwas Schutz in den Server einbringen, um unnötige Verarbeitung oder einfrieren zu vermeiden. Aus diesem Grund erstelle ich einen Thread, um eine Zeitüberschreitung für kritische Prozesse zu überprüfen.

Ich habe diese TIdSync Klasse:

type 
    TSync = class(TIdSync) 
    protected 
    procedure DoSynchronize; override; 
    end; 

procedure TSync.DoSynchronize; 
var 
    oTimeOut: TThreadTimeOut; 
begin 
    ... 
    oTimeOut := TThreadTimeOut.Create(AContext, WaitTimeOut*2, Self); 
    oTimeOut.Start; 
    ... 
    // the code below is just a test, **this is the key to my question** 
    // if something goes wrong in any subroutine of DoSynchronize, I want 
    // to stop execution of this object and destroy it. In the thread above 
    // I want to test when the timeout elapses. If this IdSync object still 
    // exists and if this routine is still executing, I want to stop execution 
    // of any routine or subroutine of this object to avoid freezing the 
    // service and stop memory consumption and CPU usage 

    while true do begin 
    Sleep(100); 
    end; 

    //If everything is OK 
    oTimeOut.Stop; 
end; 

procedure TThreadTimeOut.execute; 
var 
    IniTime: DWORD; 
begin 
    IniTime := GetTickCount; 
    while GetTickCount < IniTime + TimeOut do begin 
    Sleep(SleepInterval); 
    if StopTimeOut then 
     Exit; 
    end; 

    if ((Terminated = False) or (StopTimeOut)) and (IoHandler <> nil) then begin 
    IOHandler.Connection.IOHandler.Close; 
    IdSync.Free; //here I try to make things stop execution but the loop to test is still running 
    end; 
end; 

Dieser Code oben funktioniert Daten zu stoppen Empfangen und Senden, wenn das Timeout abgelaufen ist, aber nicht die Ausführung von TIdSync zu stoppen. Wie kann ich das machen?

Antwort

3

Es gibt keine Timeout-Logik in TIdSync (vor allem, weil es TThread.Synchronize() keine Timeout-Logik gibt, die TIdSync intern verwendet).

Sie können ein Objekt TIdSync nicht löschen, während es ausgeführt wird. Eine synchronisierte Prozedur kann nicht vorzeitig abgebrochen werden, nachdem sie zur Ausführung in die Warteschlange gestellt wurde oder gestartet wurde. Es muss erlaubt sein, zu Ende zu laufen.

TIdSync.DoSynchronize() (oder irgendein Verfahren synchronisiert mit TThread.Queue() oder TThread.Synchronize()) wird im Rahmen des Haupt UI Thread ausgeführt. Langer Code sollte in einem eigenen Thread ausgeführt werden, nicht im Hauptthread der Benutzeroberfläche. Stellen Sie sicher, dass der Hauptthread der Benutzeroberfläche nicht für die Verarbeitung neuer Nachrichten und die zeitnahe Synchronisierung von Anforderungen gesperrt ist.

Wenn Sie eine synchronisierte Prozedur anhalten möchten, müssen Sie ein TEvent Objekt oder eine andere Markierung verarbeiten, die Worker-Threads bei Bedarf signalisieren können, und die Prozedur regelmäßig überprüft, so dass sie so schnell wie möglich beendet werden kann oder durch Auslösen einer Ausnahme).

Synchronisierte Operationen von beliebig Natur sollte kurz sein, um Blockaden/Deadlocks, Ressourcenhunger, etc. zu verhindern. Sie müssen Ihr Design neu denken. Du machst Dinge falsch.

+0

Sie haben Recht in Ihren Konzepten, aber ich habe ein größeres Problem als dieser kleine Code. In diesem Fall wie oben gesagt ist nur ein Beispiel, aber ich habe an dieser Stelle, während ich eine komplexe Rountine habe, um Text zu verschlüsseln. aufgrund dieser Code ist nicht von meiner Kontrolle und ich denke, sogar unnötig implementieren alle Code in IdSync. In meinen Tests sehe ich, dass Einfrieren passieren nur während ich Debugging laufen, aber ich kann das nicht beweisen, vielleicht ist glücklich, aber gute Programmierer können nicht glücklich abhängen, haben Sie andere suggestion, um einen Code mehr speichern, und vielleicht nicht einfrieren während Debug ist runnig? –