11 Stimmen

Wie kann man eine Delphi-Anwendung (die gerade läuft) dazu bringen, etwas zu einem bestimmten Zeitpunkt/Datum zu tun?

Meine Anwendung befindet sich in der Taskleiste, wenn sie nicht verwendet wird.

Der Benutzer kann Ereignisse so konfigurieren, dass sie nach einem bestimmten Zeitplan auftreten. So kann die Aufgabe beispielsweise montags bis freitags um 17 Uhr oder jeden Mittwoch um 15 Uhr oder am 16. eines jeden Monats um 10 Uhr ausgeführt werden.

Angenommen, mein Delphi-Programm läuft immer, es startet beim Hochfahren. Wie kann ich in Delphi das Auslösen dieser geplanten Ereignisse am besten unterstützen?

Offensichtlich kann ein TTimer verwendet werden, um Ereignisse auf der Grundlage der verstrichenen Zeit zu planen, aber sie scheinen für dieses Problem nicht geeignet zu sein.

Prost

17voto

Runner Punkte 5953

Sie können meine CRON konform Cromis Scheduler (Link zu archive.org). Es unterstützt sogar einige Dinge, die cron nicht unterstützt. Intervallbasierte Ereignisse zum Beispiel und von/bis Zeitrahmen. Ich verwende es in vielen meiner Programme und es hat sich als sehr nützlich erwiesen. Es ist kostenlos, sehr leichtgewichtig, funktioniert in Threads und ist produktionserprobt. Wenn Sie weitere Hilfe benötigen, mailen Sie mir einfach.

Die anderen Möglichkeiten wären:

  1. Verwenden Sie, wie bereits vorgeschlagen, die Windows Scheduling API. Dies kann sich jedoch von Betriebssystem zu Betriebssystem ändern.
  2. Utilice JCL die eine Scheduler Unit (Komponente in der JVCL) hat, aber ich fand es schwierig, diese direkt aus dem Code heraus zu benutzen. Deshalb habe ich meine eigene geschrieben.

8voto

Leo Punkte 36757

Ich würde dafür die Microsoft Task Scheduler API verwenden:

http://msdn.microsoft.com/en-us/library/aa383614(VS.85).aspx

Es gibt Delphi Wrapper für die API, wenn Sie die "Drecksarbeit" nicht machen wollen, aber ich weiß nicht, ob es eine kostenlose Version gibt. Sie könnten einen Blick werfen auf

Wenn Sie den Microsoft Scheduler nicht verwenden wollen, gibt es Dinge wie die CronJob-Komponente, die hier verfügbar ist: http://www.appcontrols.com/components.html . Es handelt sich ebenfalls um Shareware, ist aber einfach zu implementieren (nur ein onAlert-Ereignis).

1voto

Kornel Kisielewicz Punkte 53256

Sie brauchen eine Planungskomponente. Es gibt viele verfügbar Ich kann jedoch keine kostenlose Version finden. Sie können jederzeit selbst einen erstellen, der auf TTimer basiert, oder versuchen, auf die Aufgabenplanungs-API.

Allerdings Ein Timer, der jede Minute eine Aufgabe ausführt, um zu prüfen, ob eine Aufgabe fällig ist, ist viel Einfacher.

1voto

dummzeuch Punkte 10604

Sie könnten eine Art von Interprozesskommunikation in Ihrem Programm implementieren und diese Ereignisse über ipc durch ein Programm auslösen, das vom Windows-Zeitplanungsdienst aufgerufen wird. Dieser Ansatz hat den Vorteil, dass Sie keine Benutzeroberfläche zum Einrichten des Zeitplans schreiben müssen und dass ipc sich auch auf andere Weise als nützlich erweisen könnte.

0voto

skamradt Punkte 15128

Da Ihre Anwendung läuft, können Sie das Idle-Ereignis verwenden, um zu sehen, ob ein voreingestelltes Datum/eine voreingestellte Zeit bereits verstrichen ist, und wenn ja, können Sie Ihre Zeitmessung durchführen. Der einzige Nebeneffekt dieses Ansatzes ist, dass Ihr Ereignis nicht ausgelöst wird, wenn die Anwendung beschäftigt ist, aber dann würde auch ein Timer nicht funktionieren (damit der TTimer funktioniert, muss die Nachrichtenwarteschlange verarbeitet werden, oder die Anwendung muss "Idle" sein, es sei denn, Sie verwenden einen threaded Timer).

uses
  ...,DateUtils; // contains IncMinute

type
  TForm1 = Class(TForm)
    :
    procedure FormCreate(Sender: TObject);
  private 
    fTargetDate : tDateTime;
    procedure AppIdle(Sender: TObject; var Done: Boolean);
  end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  fTargetDate := 0.0;
  Application.OnIdle := AppIdle;
  fTargetDate := IncMinute(Now,2);
end;

procedure TForm1.AppIdle(Sender: TObject; var Done: Boolean);
begin
  if (fTargetDate <> 0.0) and (Now >= fTargetDate) then
    begin
      fTargetDate := 0.0;
      ShowMessage('started');
    end;
 end;

EDIT Wenn Sie etwas mehrmals ausführen müssen, legen Sie es in einer nach Datum/Uhrzeit geordneten Liste ab und verfolgen Sie dann nur das NÄCHSTE Mal, wenn etwas ausgeführt werden soll. Wenn etwas ausgeführt wird, wird es aus der Liste entfernt (oder wieder in die Liste aufgenommen und die Liste neu sortiert).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X