2014-08-27 84 views
0

這是我的要求:
需要應用程序或任務,它以可配置的時間間隔(在Delphi中)以全天候運行。調度服務需要的建議

我到目前爲止所做的:
所以我決定去Windows服務。 然後我在Delphi中創建了windows服務。

過程是
1.創建的Windows服務啓動():

procedure TDemo.ServiceStart(Sender: TService; var Started: Boolean); 
begin 
    MyServiceThread := TMyThread.Create(False); //Call the thread 
    MyServiceThread.Resume; 
end; 

2. Windows服務站();

procedure TDemo.ServiceStop(Sender: TService; var Stopped: Boolean); 
begin 
    MyServiceThread.Terminate; 
end; 
  1. 線程的Execute方法:

    procedure TMyThread.Execute; begin MyTask(); end;

MyTask()有一些功能和它可能需要30秒到5分鐘的時間完成任務。

如果現在我開始服務,那麼它調用execute方法並調用MyTask()。然後我完成任務。它只會發生一次。因爲根本沒有循環。

然後我創建了任務調度程序和設置的10 分鐘的時間間隔,並調用其啓動我的Windows服務和 停止該批處理文件。

現在一切工作正常。每10分鐘我的任務就完成了。

什麼是所有其他的可能性,而不是任務計劃?服務本身可以做嗎?哪一個是最好的方法?

思考,發現一個解決方案:
1.Creating定時器線程內。但是Timer需要將時間設置爲Configurable one.It可能是一天或一週等等。

什麼是Timer支持的最大時間?

定時器可以嗎?

是否有其他方法可以做到這一點?

請給我一些建議去尋求更好的解決方案。

+1

爲什麼不使用系統的調度程序?爲什麼重新發明輪子? – 2014-08-27 08:06:08

回答

0

首先,我不知道你的Delphi版本,但一般TThread.Resume已被棄用。您應該使用TThread.Start。但即便如此,您也不需要啓動線程,因爲它是使用False參數創建的 - 即不是暫停狀態。

Execute()只執行一次,因爲您這樣做了。

下面的代碼是一個簡單的線程,在一段時間間隔內「執行」。

TMyThread = class(TThread) 
    private  
     fRefreshInterval: Integer; // milliseconds 
     fTerminateEvent: TEvent; 

     procedure SetRI(const Value: Integer); 
    protected 
     procedure Execute; override;  
    public 
     constructor Create(const aRefreshInterval: Integer = 600000); 
     destructor Destroy; override; 
     property RefreshInterval: Integer write SetRI; 
    end; 

//// implementation 

constructor TMyThread.Create; 
begin 
    inherited Create(False); 
    fRefreshInterval := aRefreshInterval; 
    fTerminateEvent := TEvent.Create(nil, True, False, ''); 
    Priority := tpLowest; 
    FreeOnTerminate := True; 
end; 

destructor TMyThread.Destroy; 
begin 
    try 
    if not Terminated then 
    begin 
     Terminate; 
     fTerminateEvent.SetEvent;  
    end; 

    fTerminateEvent.Free; 
    except 
    // 
    end; 
    inherited; 
end; 

procedure TMyThread.Execute; 
begin 
    while not Terminated do 
    begin 
    try 

     // your code here 

    except 
     // something bad happened 
    end; 

    fTerminateEvent.WaitFor(fRefreshInterval); 
    end; 
end; 

procedure TMyThread.SetRI(const Value: Integer); 
begin 
    InterlockedExchange(fRefreshInterval, Value); 
end; 

如果要執行你的任務每XX分鐘,你要記住你的任務執行所需的時間和應該做的事情,如:

procedure TMyThread.Execute; 
var 
    taskStartedAt: Cardinal; 
    taskDuration: Cardinal; 
begin 
    while not Terminated do 
    begin 
    taskStartedAt := GetTickCount; 
    try 

     // your code here 

    except 
     // something bad happened 
    end; 

    taskDuration := GetTickCount - taskStartedAt; 

    if (fRefreshInterval > taskDuration) then 
     fTerminateEvent.WaitFor(fRefreshInterval - taskDuration); 
    end; 
end; 

反正TTimerTask Scheduler也是選擇。

+0

感謝彼得的快速回復。定時器間隔是否可配置?我可以使用ini文件來配置計時器的時間間隔嗎? – 2014-08-27 08:55:43

+0

只要您喜歡,您可以通過其「屬性RefreshInterval」配置時間間隔。另外,您可以通過構造函數的輸入參數初始化它。 – 2014-08-27 09:02:41

0

在Windows服務中有一個計時器是一種選擇。你也可以在開始新的實例之前檢查你的前一個實例是否已經完成。但是,如果您必須不時地控制服務,這可能不是正確的選擇。

多年來,我發現Autosys是最有用的調度代理。它帶有客戶端 - 服務器模型。所以你可以控制你的Autosys客戶端工具的工作。

TechScheduler是另一種選擇,但現在它非常老派。

1

您可以使用創建計時器的方法。

現在,如果您可以基於系統時鐘安排任務(例如從下午3點開始),那麼您可以使用下一個方法。而不是改變定時器的時間間隔,以便在特定的時間觸發,讓您的定時器保持在1分鐘的時間間隔。然後,每當定時器啓動時,只需檢查系統時間是否大於預定時間。如果是你需要做什麼處理,那麼你什麼也不做。

所以現在你只需要一個有序的列表來存儲排序順序中的所有計劃任務,這樣你就不需要遍歷整個列表並檢查每個任務個體是否需要執行。

現在,如果使用系統closk不是一個選項,因爲用戶可以更改它實現自己的計數器,每當計時器觸發時它都會增加。所以現在你只需要調整你的計時邏輯到你的計數器系統。

編輯:我建議的方法是在每個任務需要一定時間的時間騎乘多人遊戲瀏覽器遊戲中共同使用。所以服務器只在某個事件發生時根據某個任務的命令執行時間而存儲,並且該任務需要多少時間才能完成。

0

我寧願去用「預定任務」方法。這就是 這樣一個任務的Windows原生方法,您只需要在計劃任務中定義的每個時間間隔創建一個名爲 的控制檯應用程序。