Announcement

Collapse
No announcement yet.

Threads beenden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Threads beenden

    Mit Hilfe eines Threads wird unter Win NT ein Verzeichnis überwacht.
    Die Anwendung schlummert in der Taskbar und kommt nur in den Vordergrund, wenn eine neue Datei im Verzeichnis abgelegt wird und sendet die Datei Über die serielle Schnittstelle an den Drucker.
    Die Applikaton enthält ein PopUpMenu, über die die Anwendung beendet
    werden soll. Zum anderen sollte über die Tastenkombination ALT+F4
    das Programm automatisch beendet werden.
    Genau da liegt das Problem: das Beenden dauert teilweise sehr lange oder
    erfolgt gar nicht. Der Rechner muss ausgeschaltet werden, dass das unter
    NT nicht so toll ist kann sich jeder denken.

    Quellcode ist wie im Borland Delphi 4 - Buch vom Hanser Verlag:

    { Thread-Code }
    procedure TWatch.Execute;
    begin

    changehandle:=FindFirstChangeNotification(PChar(wa tchpath),FALSE,FILE_NOTIFY_CHANGE_FILE_NAME);

    if changehandle <> INVALID_HANDLE_VALUE then begin
    while True do begin // normalerweise eine Endlosschleife
    if WaitForSingleObject(changehandle,500)= WAIT_OBJECT_0 then begin
    synchronize(Drucke_Was);
    end;
    FindNextChangeNotification(changehandle);
    if Terminated then break;
    end; { while }
    end; { if changehandle }
    end; { procedure }

    procedure TForm1.WMTASKBAREVENT(var message: TMessage);
    var point : TPoint;
    begin
    case message.LParamLo of
    WM_LBUTTONDBLCLK : begin
    InfoBox.show;
    end;
    WM_RBUTTONDOWN : begin
    GetCursorPos(point);
    popupmenu1.popup(point.x,point.y);
    end;
    end;
    end;

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    TaskBarRemoveIcon;
    Application.Terminate;
    Action := caFree;
    end;

    procedure TForm1.Beenden1Click(Sender: TObject);
    begin
    Application.Terminate;
    form1.Close;
    end;

    Wer weiss Rat????

  • #2
    Hallo, bau in FormClose noch die Funktionsaufrufe TerminateProcess und FindCloseChangeNotification ein
    Günther

    Comment


    • #3
      FindCloseChangeNotification hatte ich schon in Destroy-Methode eingebaut, in formclose (TerminateProcess und FindCloseChangeNotification)
      bewirkt es leider auch nichts

      Comment


      • #4
        Hallo,

        gibt es einen Grund, <b>Terminate</b> von Hand aufzurufen? In der Delphi-Hilfe steht folgendes: "<i>Terminate ruft die Funktion PostQuitMessage der Windows-API auf, um die Anwendung kontrolliert zu beenden. Die Methode Terminate wirkt somit nicht direkt. Terminate wird als Reaktion auf die Botschaft WM_QUIT und beim Schließen des Hauptformulars automatisch aufgerufen.</i>".

        Was passiert, wenn die Methode <b>Close</b> des Hauptformulars aufgerufen wird?

        Das grundlegende Problem ist, das der primäre Thread des Hauptformulars auf das Ende des zweiten Threads warten muss. Erst dann, wenn der Thread terminiert, darf sich das Programm selbst beenden. Eine Möglichkeit wäre zum Beispiel, eine private Botschaft zu Thread zu schicken, um dessen Ende definiert im eigenen Programm bestimmen zu können:
        <pre>
        aHandle := GetCurrentThread;
        repeat
        dwResult := MsgWaitForMultipleObjects(1, aHandle, False, dwTime, QS_ALLINPUT);
        case dwResult of
        WAIT_OBJECT_= : // Ereignis auswerten
        WAIT_OBJECT_0 + 1 : // Thread beenden
        WAIT_TIMEOUT : bTimeOut := True;
        end;
        until bTimeOut;
        CloseHandle(aHandle);
        ...
        </pre>
        Im ersten Schritt ermittelt die Win32-API-Funktion <b>GetCurrentThread</b> das Handle auf den Thread des Servers. Damit kann der Aufruf von <b>MsgWaitForMultipleObject</b> auf Aktionen für dieses Handle warten - wobei durch den Parameter QS_ALLINPUT alle Botschaften erkannt werden. Wenn diese Funktion zurückkehrt, ist entweder eine Botschaft in der zugehörigen Botschaftswarteschlange des Threads vorgefunden worden (WAIT_OBJECT_0 +1), oder
        der TimeOut-Wert überschritten worden (WAIT_TIMEOUT). Ist letzteres der Fall, wird die Repeat-Schleife verlassen, das angeforderten Thread-Handle geschlossen. Der primäre Thread der Anwendung muss dann nur eine beliebige Botschaft zum Thread posten, um diesen zu stoppen.

        Alternativ dazu steht auch noch <b>TThread.WaitFor</b> zur Verfügung, um auf das Ende des abgespalteten Threads zu warten:
        <pre>
        procedure TFormMain.FormDestroy(Sender: TObject);
        begin
        if Assigned(FOnCreateThread) then
        begin
        FOnCreateThread.Terminate;
        FOnCreateThread.WaitFor;
        end;
        end;
        </pre>
        &#10

        Comment

        Working...
        X