Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Timer in Thread führt OnTime nicht aus... (https://www.delphipraxis.net/89773-timer-thread-fuehrt-ontime-nicht-aus.html)

7down 5. Apr 2007 14:05


Timer in Thread führt OnTime nicht aus...
 
Hallo,

ich hab in meinem Programm mehrere Threads und möchte eine Art Timeout für die Threads coden, dh sobald der Thread länger als x Minuten existiert, soll er neugestartet werden.

Mein Problem ist aber, dass der Timer eifnach nichts macht, hab auch schon nen Breakpoint im OnTimeout gesetzt, nützt nichts, der führt das einfach nicht aus. Der Timer wird im Konstruktor des Threads erstellt. Interval hab ich auch testweise schon auf 1 gehabt etc etc...

Hier mal mein Code:
Delphi-Quellcode:
  Timeout := TTimer.Create(nil);
  Timeout.Interval := 1000;
  Timeout.OnTimer := OnTimeout;
  Timeout.Enabled := True;

[...]

procedure TMyThread.OnTimeout(Sender: TObject);
begin
fmain.mdebug.Lines.Add('timeout');
  //Restart;
end;
Versteht das irgendwer??

DGL-luke 5. Apr 2007 14:32

Re: Timer in Thread führt OnTime nicht aus...
 
ähm... sicher dass du das in MyThread definiert haben willst?

ich würd das außerhalb des Threads definieren und den Thread von außerhalb abschießen und neustarten.

EDIT: Merke: VCL ist nicht threadsicher!

Bernhard Geyer 5. Apr 2007 14:53

Re: Timer in Thread führt OnTime nicht aus...
 
Ich denke das Problem ist das TTimer auf Windows-Messages basiert und diese AFAIK nicht so im Thrad "durchschlagen".
Es gibt aber AFAIK 'ne WinAPI-Funktion um per Callback einen Timer zu haben.


Zitat:

Zitat von DGL-luke
EDIT: Merke: VCL ist nicht threadsicher!

Wobei das Grundproblem bei der Win32-API liegt. Siehe Beitrag von A. Kosch

7down 5. Apr 2007 16:59

Re: Timer in Thread führt OnTime nicht aus...
 
Hm, danke schon mal..

Wie könnte ich sonst ein Timeout realisieren? Ich hab acuh schon versucht im TMyThread nochmal einen Thread (TTimeoutThread) zu integrieren, welcher einfach x Minuten "sleept" und dann den Thread restarted. Hat aber irgendwie nicht so wirklich geklappt..

Wär nice wenn mir da jmd helfen könnte.

Danke und ciao

Jens Schumann 26. Jun 2007 09:17

Re: Timer in Thread führt OnTime nicht aus...
 
Hallo,
hatte ungefähr 10 Minuten das gleiche Problem. Auf der Suche nach einer Lösung bei ich folgendeSeite gefunden.
Da TTimer AllocateHWND verwendet habe ich nicht weiter gesucht und mich für eine Threadlösung entschieden.
Delphi-Quellcode:
unit hyps_ServerTimerThread_impl;

interface

uses
  Windows, Messages, Classes;

const

  PM_TIMERTHREAD_EVENT = WM_APP+10002;

type

  TTimerThread = class(TThread)
  private
    { Private-Deklarationen }
    FSinkThreadID : THandle;
    FInterval    : DWord;
  protected
    procedure Execute; override;
  public
    constructor Create(CreateSuspended: Boolean);
    property Interval    : DWord read FInterval write FInterval;
    property SinkThreadID : THandle read FSinkThreadID write FSinkThreadID;
  end;

implementation


{ TimerThread }

constructor TTimerThread.Create(CreateSuspended: Boolean);
begin
  FInterval:=5000;
  inherited Create(CreateSuspended);
  FreeOnTerminate:=True;
end;

procedure TTimerThread.Execute;
begin
  While Not Terminated do
    begin
    Sleep(FInterval);
    If (FSinkThreadID<>0) then
      PostThreadMessage(FSinkThreadID,PM_TIMERTHREAD_EVENT,0,0);
    end;
end;

end.
Die Genuigkeit bei der Einhaltung des Intervals ist für mich völlig uninteressant.
Hauptsache es wird mehr oder weniger periodisch aufgerufen.

Delphi-Quellcode:
  THypsClientThread = Class(TServerClientThread)
  private
    ...
    FUploadTimer       : TTimerThread;

constructor THypsClientThread.Create(CreateSuspended: Boolean; ASocket: TServerClientWinSocket);
begin
  FClientStream:=TMemoryStreamExt.Create;
  FUploadTimer:=TTimerThread.Create(True);
  inherited Create(CreateSuspended, ASocket);
  FUploadTimer.SinkThreadID:=ThreadID;
end;

procedure THypsClientThread.ClientExecute;
var
  Msg              : tagMsg;
begin
  ...
        If PeekMessage(Msg, 0, PM_TIMERTHREAD_EVENT, PM_TIMERTHREAD_EVENT, PM_REMOVE) then
          begin
          If Msg.message=PM_TIMERTHREAD_EVENT then
            UploadTimerEvent;
          end;
  ...
end;
Funktionsweise:
THypsClientThread erzeugt im Create den TTimerThread. an TTimerThread wird die ThreadID von THypsClientThread übergeben.
Der TTimerThread wird über Resume und Suspend aktiviert. Wenn der TTimerThread aktiviert ist wird über PostThreadMessage
über die THypsClientThread.ThreadID eine Botschaft an THypsClientThread gesendet. In THypsClientThread wird beim Empfang
der Botschaft die Methode UploadTimerEvent aufgerufen. Funktioniert prima.

Jetzt Frage: Ist die Sache threadsafe?

Luckie 26. Jun 2007 09:28

Re: Timer in Thread führt OnTime nicht aus...
 
Einen Timer in einen Thread halte ich für nicht sehr glücklich. Warum startest du nicht den Thread und merkst dir, wann du ihn gestartet hast und wenn die Zeit um (-> Timer) ist beendest du ihn.

Jens Schumann 26. Jun 2007 09:33

Re: Timer in Thread führt OnTime nicht aus...
 
Hallo Luckie,
hast Du mir geantwortet? Wenn ja- ich habe keinen TTimer verwendet. Weil AllocateHWND nicht threadsafe ist.
Aus einem Thread heraus muss ich in besitmmtem Abständen prüfen ob eine Datei vorhanden ist.
Dafür wollte ich ursprünglich einen TTimer verwenden. Davon bin aber ab und verwende stattdessen einen weitren Thread.

Robert Marquardt 26. Jun 2007 09:51

Re: Timer in Thread führt OnTime nicht aus...
 
Die Loesung mit Sleep ist schon ganz gut, aber der Nachteil ist das der Thread nicht vorzeitig durch Terminate beendet werden kann.
Ein Event muesste her auf den man mit WaitForSingleObject und Timeout wartet. Leider ist TThread nicht dafuer geeignet. Terminate ist nicht virtuell.

SirThornberry 26. Jun 2007 10:04

Re: Timer in Thread führt OnTime nicht aus...
 
das Problem beim Timer im Thread ist nicht das es nicht Threadsafe ist sondern das ihr keine Nachrichtenschleife habt. Und ohne Nachrichtenschleife werden auch keine Nachrichten ausgewertet. Somit auch keine Timer-messages.

DGL-luke 26. Jun 2007 11:03

Re: Timer in Thread führt OnTime nicht aus...
 
Per WinAPI kanns man aber ein Hier im Forum suchenMessage-only-window erzeugen, wo man dann ein handle und eine nachrichtenschleife hat.

Natürlich ist TTimer im Thread dann immer noch nicht elegant...


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:30 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz