回答
您有兩個簡單的選擇,使用timer:send_interval/2
或erlang:send_after/3
。 send_interval
更容易設置,而send_after
(當在Erlang模塊中使用時)更加可靠,因爲它是內置函數,請參見Efficiency Guide。
使用send_after
還可以確保gen_server
過程不會過載。如果您使用的是send_interval
函數,則無論進程是否可以跟上,都會收到消息。在handle_info
返回之前調用send_after
,只有在處理完上一個消息後纔會安排一條新消息。如果你想要更準確的時間跟蹤,你仍然可以安排一個send_after
動態設置的時間低於?INTERVAL
(甚至0)以趕上。
我會建議大意如下的東西在你的gen_server
:
-define(INTERVAL, 60000). % One minute
init(Args) ->
... % Start first timer
erlang:send_after(?INTERVAL, self(), trigger),
...
handle_info(trigger, State) ->
... % Do the action
... % Start new timer
erlang:send_after(?INTERVAL, self(), trigger),
...
相反trigger
,如果它是需要的,像{trigger, Count}
或東西,你可以用一個狀態送東西。
在gen_server中實際上有一個內置的機制來完成同樣的事情。 如果gen_server
中的init,handle_call,handle_cast或handle_info方法的響應元組的第三個元素是一個整數,則在該時間段之後將以毫秒爲單位發送一個timeout
消息...應該使用handle_info處理該消息。例如:
init(Args) -> ... % Start first timer {ok, SomeState, 20000}. %% 20000 is the timeout interval handle_call(Input, From, State) -> ... % Do something ... % Do something else {reply, SomeState, 20000}. %% 20000 is the timeout interval handle_cast(Input, State) -> ... % Do something ... % Do something else {noreply, SomeState, 20000}. %% 20000 is the timeout interval %% A timeout message is sent to the gen_server to be handled in handle_info %% handle_info(timeout, State) -> ... % Do the action ... % Start new timer {noreply, SomeState, 20000}. %% "timeout" can be sent again after 20000 ms
爲什麼我得到-1票的任何理由? – 2011-05-05 09:45:23
這是真的。雖然這意味着你必須操縱超時,這可能不是一個壞主意。 – 2011-05-05 09:57:28
'timeout'不適用於定期執行。當這段時間沒有任何事情發生時,它打算髮起一些行動或終止。即使通過某些系統('sys','proc_lib',...)操作,每次操作都會終止該超時。不久之後,使用超時是不鼓勵的依賴,除了一些「維護」的東西,如自動終止或清理。 – 2011-05-05 09:58:26
精確控制定時器,你可能需要使用erlang:start_timer
,並保存您創建的每個定時器參考。
erlang:start_timer
有erlang:send_after
一個微小的差別,看http://www.erlang.org/doc/man/erlang.html#start_timer-3和http://www.erlang.org/doc/man/erlang.html#send_after-3
示例使用情形:
init(Args) ->
...
TRef = erlang:start_timer(?INTERVAL, self(), trigger),
State = #state{tref = TRef},
...
handle_info({timeout, _Ref, trigger}, State) ->
%% With this cancel call we are able to manually send the 'trigger' message
%% to re-align the timer, and prevent accidentally setting duplicate timers
erlang:cancel(State#state.tref),
...
TRef = erlang:start_timer(?INTERVAL, self(), trigger),
NewState = State#state{tref = TRef},
...
handle_cast(stop_timer, State) ->
TRef = State#state.tref,
erlang:cancel(TRef),
%% Remove the timeout message that may have been put in our queue just before
%% the call to erlang:cancel, so that no timeout message would ever get
%% handled after the 'stop_timer' message
receive
{timeout, TRef, _} -> void
after 0 -> void
end,
...
- 1. 在Erlang R19中實現gen_server
- 2. 如何使用GridBagBayout執行此操作?
- 3. 如何在ASP.NET/WCF中定期執行某些操作?
- 4. 何時在Erlang/OTP應用程序中使用gen_server
- 5. erlang-sqlite3如何使用綁定參數執行插入語句
- 6. 如何使用數據綁定來執行此操作
- 7. Erlang啓動gen_server被阻止的代碼
- 8. 如何自動執行定期執行作業的WCF服務
- 9. Erlang erl_call導致gen_server模塊退出
- 10. Erlang:在beam可執行文件中使用gb_tree函數,記錄操作?
- 11. 執行操作
- 12. 執行操作
- 13. jQuery插件來執行日期操作
- 14. 在查詢中執行日期操作
- 15. 如何在使用erlang編譯erlang時節省鍵盤操作時間?
- 16. 如何使用numpy對行數組執行操作?
- 17. 使用gen_server處理Erlang異步消息:cast/2
- 18. Erlang嘗試使gen_server:調用很多響應
- 19. 想要使用struct tm執行日期/時間值操作
- 20. 如何測試使用Jasmine在回調中執行的操作
- 21. 如何使用JavaScript執行基本的服務器端操作?
- 22. 如何在使用javascript的Azure SQL Server上執行操作?
- 23. 如何使用LINQ執行這種不同的操作?
- 24. 如何使用正確的OOP執行此操作?
- 25. 如何使用操作表執行文本字段的重置?
- 26. 如何指定不執行任何操作的導軌路線
- 27. 如何阻止jQuery Mobile使用window.location執行任何操作?
- 28. 如何在休眠模式下執行日期操作
- 29. R - 如何執行跨年日期操作?
- 30. 如何使用用戶代理執行此操作?
這是偉大的!這正是我目前所做的。謝謝! – 2011-05-04 15:05:54
最終會不會出現這種情況,因爲計時器每6000+ <動作持續時間> ms會觸發? – 2015-08-19 07:26:38
@PatrickOscity當然,它可能。如果你想真的確定,你可以計算出未來的時間來安排它,然後計算確切的毫秒數。 – 2015-08-19 08:33:13