c# 中有三種定時器,system.windows.forms
中的定時器和system.timers.timer
的工作方式是完全一樣的,所以,這裡我們僅討論system.timers.timer
和system.threading.timer
先來看乙個例子:
class program
static void start()
}public class foo
private void timer_elapsed(object sender, system.timers.elapsedeventargs e)
~foo()
}
執行結果如下:
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
...
在start
方法結束後,foo
例項已經失去了作用域,按理說應該被**,但實際並沒有(因為析構函式沒有執行,所以肯定例項未被**)。
這就是定時器的保活機制,因為定時器需要執行timer_elapsed
方法,而該方法屬於foo
例項,所以foo
例項被保活了。
但多數時候這並不是我們想要的結果,這種結果導致的結果就是記憶體洩露,解決方案是:先將定時器dispose
。
public class foo : idisposable
}
乙個很好的準則是:如果類中的任何欄位所賦的物件實現了idisposable
介面,那麼該類也應當實現idisposable
介面。
在這個例子中,不止dispose
方法,stop
方法和設定autoreset = false
,都能起到釋放物件的目的。但是如果在stop
方法之後又呼叫了start
方法,那麼物件依然會被保活,即便stop
之後進行強制垃圾**,也無法**物件。
system.timers.timer
和system.threading.timer
的保活機制是類似的。
保活機制是由於定時器引用了例項中的方法,那麼,如果定時器不引用例項中的方法呢?
要消除定時器對例項方法的引用也很簡單,將timer_elapsed
方法改成靜態的就好了。(靜態方法屬於類而非例項。)
改成靜態方法後再次執行示例,結果如下:
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
---------- end ----------
system.timers.timer elapsed.
system.timers.timer elapsed.
system.timers.timer elapsed.
...
foo
例項是被銷毀了(析構函式已執行,列印出了 end),但定時器還在執行,這是為什麼呢?
這是因為,.net framework 會確保system.timers.timer
的存活,即便其所屬例項已經被銷毀**。
如果改成system.threading.timer
,又會如何?
class program
static void start()
}public class foo2
static void timertick(object state)
~foo2()
}
注意,這裡的timertick
方法是靜態的。執行結果如下:
system.threading.timer elapsed.
system.threading.timer elapsed.
system.threading.timer elapsed.
system.threading.timer elapsed.
system.threading.timer elapsed.
---------- end ----------
可見,隨著foo2
例項銷毀,_timer
也自動停止並銷毀了。
這是因為,.net framework 不會儲存啟用system.threading.timer
的引用,而是直接引用**委託。
C 定時器保活機制引起的記憶體洩露問題解決
c 中有三種定時器,system.windows.forms 中的定時器和 system.timers.timer 的工作方式是完全一樣的,所以,這裡我們僅討論 system.timers.timer 和 system.threading.timer 1 定時器保活 先來看乙個例子 class pr...
TCP保活定時器
tcp有keepalive功能,它和http的keepalive功能目的不一樣。tcp伺服器希望知道客戶端是否崩潰 重新啟動或者中間路由不通。保活定時器就提供這種功能。在進一步介紹tcp的保活定時器前,先了解乙個概念 長連線和短連線。tcp是長連線 長連線 建立乙個連線,多個請求復用這個連線,最後再...
(23)TCP的保活定時器
一 簡介 對於運輸層是否應該存在保活定時器的討論一直都有,一些專家覺得這應該有應用層自行維護。如果乙個給定的連線在2小時內沒有任何動作,那麼伺服器就向客戶傳送乙個探查報文段。客戶主機必須處於以下4個狀態之一。1 客戶主機依然正常執行,並從伺服器可達。客戶的tcp響應正常,而伺服器也知道對方的正常工作...