請問如何寫排程程式? |
尚未結案
|
小蟲蟲
一般會員 發表:38 回覆:55 積分:23 註冊:2002-03-13 發送簡訊給我 |
|||||
Miles
尊榮會員 發表:27 回覆:662 積分:622 註冊:2002-07-12 發送簡訊給我 |
Hello :
你可以先寫一個計算時間的函式(毫秒), 再直接填入Timer中, 這樣就不會有每秒觸動的情形, 譬如:
function CountTime(ProcessTime: TDateTime): Integer; var NowTime : TDateTime; begin NowTime := Time; Result := Trunc((ProcessTime - NowTime) * 24 * 60 * 60 * 1000); end; procedure TForm1.Button1Click(Sender: TObject); var : MyProcessTime; begin MyProcessTime := StrToTime('18:00:00'); Timer1.Enabled := False; Timer1.Interval := CountTime(MyProcessTime); Timer1.Enabled := True; end;
------
我不是高手, 高手是正在銀幕前微笑的人. |
||||
小蟲蟲
一般會員 發表:38 回覆:55 積分:23 註冊:2002-03-13 發送簡訊給我 |
|||||
Dalman
一般會員 發表:27 回覆:22 積分:24 註冊:2002-08-21 發送簡訊給我 |
我提出我的思考佈局給你參考看看: 一、使用 Thread 來分派處理不同時間點的排程工作執行。
二、使用 client-side 資料庫(如 Access)來儲存各個時間點工作資訊。
三、利用 Timer 每隔 n 分鐘去輪詢資料表 m 筆記錄,看是否有指定排程工作,若是有的話便立即建立排程 Thread 執行,並在資料表該筆記錄上更新狀態資料。
四、若有需要,可以在排程 Thread 執行完成後,將日誌(log)資訊寫入資料庫內,做為以後歷史查閱或統計資料來源。
五、連 Timer 都可以使用 Thread 來實做,而且幾乎感覺不到 CPU loading 吃重(我因專案實務而得知的且有應用過,Timer為每五秒一次輪詢 MSSQL 資料五筆,CPU loading 低於 3%,CPU Speed=1.4 GHz)。
六、呵呵,你可能會問這個 ThreadTimer 哪裡得?自己有參考網路上他人發表程式碼實做一個 _TThreadTimer 單元應用於專案上。 希望上述文字可以給你一個明確方向。
|
||||
小蟲蟲
一般會員 發表:38 回覆:55 積分:23 註冊:2002-03-13 發送簡訊給我 |
|||||
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
要按使用者設定時間作事,一定得有 Timer ,而 Timer 準不準並不重要,重要的是在 Timer 內作什麼?
依你的需求,在 Timer 內應先讀取目前的時間,判斷是否有某個設定的排程時間已到且未執行,如果有,則去讀取該排程相關的資料,依設定資料叫用其他程式,同時設定此排程已執行,如果需要,則重新設定此排程的下一次執行時間,並重新此新的排程尚未執行,如此可以作到每小時執行一次或每十分鐘執行一次。
而排程設定的時間資料可以直接放在記憶體中,不要每次 Timer 來才去讀設定檔,這樣才能減少磁碟 IO 才不會造成 CPU Loading,時間在 BCB/Delphi 中使用 double 來存才占 8 bytes 不會有太占記憶體。這樣即使每秒比對一次對 CPU 的 Loading 應該都在 1% 以下,即使是有 100 筆排程設定值以 C500 的 CPU 比對 100 筆的浮點數大小再加一個 bool 是否已執行的旗標應該是沒什麼問題。
是否開多個 ThreadTimer 來處理每一個排程?以上述的作法應該是可以不用了,只需要主程式的一個 Timer 就夠了,而這個 Timer 如果是 ThreadTimer 當然會更好,這樣就可以讓使用者設定此排程軟體的優先權。 沒空更新的網頁...
------
http://www.ViewMove.com |
||||
kkccgg
初階會員 發表:50 回覆:54 積分:30 註冊:2002-07-28 發送簡訊給我 |
|||||
jackkcg
站務副站長 發表:891 回覆:1050 積分:848 註冊:2002-03-23 發送簡訊給我 |
參考看看
PostgreSQL VS Delphi
http://pgsql.vip.idv.tw/viewtopic.php?t=398
------
********************************************************** 哈哈&兵燹 最會的2大絕招 這個不會與那個也不會 哈哈哈 粉好 Delphi K.Top的K.Top分兩個字解釋Top代表尖端的意思,希望本討論區能提供Delphi的尖端新知 K.表Knowlege 知識,就是本站的標語:Open our mind |
||||
Dalman
一般會員 發表:27 回覆:22 積分:24 註冊:2002-08-21 發送簡訊給我 |
|||||
miga
初階會員 發表:61 回覆:92 積分:30 註冊:2002-08-27 發送簡訊給我 |
|||||
小蟲蟲
一般會員 發表:38 回覆:55 積分:23 註冊:2002-03-13 發送簡訊給我 |
謝謝大家幫忙,目前我是使用2個ThreadTimer來做排程的動作。這個Threadtimer是我在網路上找到的,與前一篇大大所Post的類似,但看起來前一篇所寫的比較完整。如果大家有需要,可以參考參考。
至於為什麼我用2個ThreadTimer呢?我做了一個測試:
//當按下Button時,產生一個ThreadTimer,並設定Interval為1秒。
procedure TForm1.Button1Click(Sender: TObject);
begin
FTimer := TThreadedTimer.Create(Self);
FTimer.Interval := 1000;
FTimer.Enabled := True;
FTimer.OnTimer := TimerProcedure;
FCount := -1;
end; //在TimerProcedure內做的事是將系統時間列在Memo1中,
//並且使之超過Timer的Interval
procedure TForm1.TimerProcedure(Sender: TObject);
var
ADate, ATime: TDateTime;
iCount: integer;
strDT: string;
iIndex: integer;
begin
Inc(FCount);
ADate := Date Time;
Memo1.Lines.Add('Begin--' DateTimeToStr(ADate));
for iCount := 0 to 1000 do
begin
ADate := Now;
strDT := DateTimeToStr(ADate);
ADate := StrToDateTime(strDT);
Memo1.Lines.Add('During--' DateTimeToStr(ADate));
end;
Memo1.Lines.Add('End--' DateTimeToStr(ADate));
end; 結果:
Begin--2002/10/30 上午 10:13:59
During--2002/10/30 上午 10:13:59
During--2002/10/30 上午 10:13:59
...
During--2002/10/30 上午 10:14:00
During--2002/10/30 上午 10:14:00
...
During--2002/10/30 上午 10:14:01
During--2002/10/30 上午 10:14:01
...
During--2002/10/30 上午 10:14:02
During--2002/10/30 上午 10:14:02
...
During--2002/10/30 上午 10:14:03
During--2002/10/30 上午 10:14:03
...
During--2002/10/30 上午 10:14:04
During--2002/10/30 上午 10:14:04
...
During--2002/10/30 上午 10:14:05
During--2002/10/30 上午 10:14:05
...
End--2002/10/30 上午 10:14:05
Begin--2002/10/30 上午 10:14:06
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
如果在OnTimer所做的事超過Timer的Interval,則可能會跳過幾個Interval。我的排程程式是以秒為單位,並且不予許跳秒的事情發生。
所以,我的做法為:
一、一個Timer負責計算時間,如果時間到的時候,將要做的事情寫入一ThreadList中。
二、第二個Timer負責每隔五秒去檢查ThreadList內有沒有東西,如果有,則取出,並從List中刪除,執行之。
三、原本是想說當第一個Timer時間到時,立即產生一個Thread,由這個Thread去做要做的事,這是我的理想做法,有可能在同一時間會有好幾個Thread在執行。不幸地,我的程式會有同步的問題,且目前我沒這個需求。 再次謝謝大家的幫忙,也提出我的做法,讓大家參考參考
|
||||
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
引言: 如果在OnTimer所做的事超過Timer的Interval,則可能會跳過幾個Interval。我的排程程式是以秒為單位,並且不予許跳秒的事情發生。 所以,我的做法為: 一、一個Timer負責計算時間,如果時間到的時候,將要做的事情寫入一ThreadList中。 二、第二個Timer負責每隔五秒去檢查ThreadList內有沒有東西,如果有,則取出,並從List中刪除,執行之。 三、原本是想說當第一個Timer時間到時,立即產生一個Thread,由這個Thread去做要做的事,這是我的理想做法,有可能在同一時間會有好幾個Thread在執行。不幸地,我的程式會有同步的問題,且目前我沒這個需求。 再次謝謝大家的幫忙,也提出我的做法,讓大家參考參考您的第一個 Timer 計時以秒為單位,試問是您自己計時嗎? 還是每次會讀取系統時間呢? 如果您自己計時,而不讀取系統時間,那這樣的排程一定會不準的! 特別是在支援「暫停」、「休眠」的電腦,你的 Timer 會因系統暫停或休眠而停止計時喔。 沒空更新的網頁...
------
http://www.ViewMove.com |
||||
小蟲蟲
一般會員 發表:38 回覆:55 積分:23 註冊:2002-03-13 發送簡訊給我 |
引言: 您的第一個 Timer 計時以秒為單位,試問是您自己計時嗎? 還是每次會讀取系統時間呢? 如果您自己計時,而不讀取系統時間,那這樣的排程一定會不準的!請教,什麼是自己計時與每次讀取系統時間? 我目前的做法是在ThreadTimer內 if WaitForSingleObject(gEventObj, Interval) = WAIT_TIMEOUT then begin Synchronize(fireOnTimer); end; 等待Interval。 當Interval時間到,而觸發TimerProcedure時,讀取系統時間,看看是否需要執行排程。 請問這種做法安全嗎? |
||||
dllee
站務副站長 發表:321 回覆:2519 積分:1711 註冊:2002-04-15 發送簡訊給我 |
引言:我所要說的只是,必需要「讀取系統時間」才不會有問題。 而所謂的自己計時是:假設 Timer 可以每秒執行一次,自己寫程式計秒。 但不論是什麼 Timer 都有可能會不準,所以一定不能自己計時,而要在 OnTimer 時用 Now() 或其他的函式讀取系統時間。 沒空更新的網頁...引言: 您的第一個 Timer 計時以秒為單位,試問是您自己計時嗎? 還是每次會讀取系統時間呢? 如果您自己計時,而不讀取系統時間,那這樣的排程一定會不準的!請教,什麼是自己計時與每次讀取系統時間? 我目前的做法是在ThreadTimer內 if WaitForSingleObject(gEventObj, Interval) = WAIT_TIMEOUT then begin Synchronize(fireOnTimer); end; 等待Interval。 當Interval時間到,而觸發TimerProcedure時,讀取系統時間,看看是否需要執行排程。 請問這種做法安全嗎?
------
http://www.ViewMove.com |
||||
brucetsao
一般會員 發表:1 回覆:33 積分:11 註冊:2002-09-11 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |