国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

詳解C#中的定時器Timer類及其垃圾回收機制

2019-10-29 21:29:10
字體:
供稿:網(wǎng)友
這篇文章主要介紹了C#中的定時器Timer類及其垃圾回收機制,講解了Timer相關(guān)的單線程異步工作,需要的朋友可以參考下
 

關(guān)于C# Timer類  在C#里關(guān)于定時器類就有3個

C# Timer使用的方法1.定義在System.Windows.Forms里

C# Timer使用的方法2.定義在System.Threading.Timer類里  "

C# Timer使用的方法3.定義在System.Timers.Timer類里

下面我們來具體看看這3種C# Timer用法的解釋:

(1)System.Windows.Forms.Timer

應(yīng)用于WinForm中的,它是通過Windows消息機制實現(xiàn)的,類似于VB或Delphi中的Timer控件,內(nèi)部使用API  SetTimer實現(xiàn)的。它的主要缺點是計時不精確,而且必須有消息循環(huán),Console  Application(控制臺應(yīng)用程序)無法使用。   
  
(2)System.Timers.Timer

和System.Threading.Timer非常類似,它們是通過.NET  Thread  Pool實現(xiàn)的,輕量,計時精確,對應(yīng)用程序、消息沒有特別的要求。

(3)System.Timers.Timer還可以應(yīng)用于WinForm,完全取代上面的Timer控件。它們的缺點是不支持直接的拖放,需要手工編碼。

C# Timer用法實例

使用System.Timers.Timer類System.Timers.Timer t =  new System.Timers.Timer(10000); //實例化Timer類,設(shè)置間隔時間為10000毫秒;  t.Elapsed +=  new System.Timers.ElapsedEventHandler(theout); //到達時間的時候執(zhí)行事件;  t.AutoReset = true; //設(shè)置是執(zhí)行一次(false)還是一直執(zhí)行(true);  t.Enabled = true; //是否執(zhí)行System.Timers.Timer.Elapsed事件;   public void theout( object source,  System.Timers.ElapsedEventArgs e)   {    MessageBox.Show("OK!");   } 

 
Timer的垃圾回收機制
通常我們需要定時執(zhí)行一段任務(wù)的時候,我們就需要定時器,這時我們就可以使用c# System.Threading空間中的 Timer定時器;他是個異步定時器,時間到時每次都是在線程池中分配一個線程去執(zhí)行任務(wù)。下面我們來看一個有趣的例子:

class Program  {    static void Main(string[] args)    {      Timer timer = new Timer(TimerCallback,null,0,2000);            Console.ReadLine();    }     private static void TimerCallback(object o)    {      Console.WriteLine("in TimerCallback method");      GC.Collect();           }  }

當我們在debug模式下運行該段程序時,正如我們期盼的那樣程序會每隔2秒鐘執(zhí)行該方法,打印出"in TimerCallback method”,而在release模式下執(zhí)行的時候,只執(zhí)行一次該方法,字符串只打印一次。在這里我們在調(diào)用TimerCallback方法時,強制執(zhí)行垃圾回收器,說明在release模式下,垃圾回收器執(zhí)行回收算法時,首先假設(shè)所有對象都是可回收的,當將Timer對象賦值給變量t后,t沒有在被引用,因此也就沒有變量引用Timer對象,所以垃圾收集這時會回收Timer對象。那么為什么在debug模式下卻能夠運行能,這跟c#編譯器的優(yōu)化方式有關(guān),在release模式下編譯器做了相關(guān)的優(yōu)化操作。而在debug模式下,timer對象的生成期是方法的結(jié)束,這樣做也是為了調(diào)試的方便。要不然在調(diào)試時,我們執(zhí)行到Timer timer = new Timer()后想看timer的值時,已經(jīng)被垃圾回收器給回收了,這是我們不期望看到的結(jié)果,編譯器如何處理的,我們可以看看編譯器在release模式下和debug模式下對上面的代碼編譯后生成的IL對比我們既知結(jié)果。

release模式編譯生成的IL:

.method private hidebysig static void Main(string[] args) cil managed{ .entrypoint // Code size    32 (0x20) .maxstack 8 IL_0000: ldnull IL_0001: ldftn   void GCTest.Program::TimerCallback(object) IL_0007: newobj   instance void [mscorlib]System.Threading.TimerCallback::.ctor(object,                                           native int) IL_000c: ldnull IL_000d: ldc.i4.0 IL_000e: ldc.i4   0x7d0 IL_0013: newobj   instance void [mscorlib]System.Threading.Timer::.ctor(class [mscorlib]System.Threading.TimerCallback,                                       object,                                       int32,                                       int32) IL_0018: pop IL_0019: call    string [mscorlib]System.Console::ReadLine() IL_001e: pop IL_001f: ret} // end of method Program::Main

debug模式下生成的IL:

method private hidebysig static void Main(string[] args) cil managed{ .entrypoint // Code size    33 (0x21) .maxstack 4 .locals init ([0] class [mscorlib]System.Threading.Timer timer) IL_0000: nop IL_0001: ldnull IL_0002: ldftn   void GCTest.Program::TimerCallback(object) IL_0008: newobj   instance void [mscorlib]System.Threading.TimerCallback::.ctor(object,                                           native int) IL_000d: ldnull IL_000e: ldc.i4.0 IL_000f: ldc.i4   0x7d0 IL_0014: newobj   instance void [mscorlib]System.Threading.Timer::.ctor(class [mscorlib]System.Threading.TimerCallback,                                       object,                                       int32,                                       int32) IL_0019: stloc.0 IL_001a: call    string [mscorlib]System.Console::ReadLine() IL_001f: pop IL_0020: ret} // end of method Program::Main

從生成的IL中我們可以看出在debug模式下,生成IL比在release模式下多了19行紅色字體的IL指令碼,該指令碼的作用是將15行生成的引用Timer對象的棧上的變量存放到局部變量0中。所以使得在debug模式下該t還被引用,不能夠回收Timer對象,所以也能出現(xiàn)我們期盼的結(jié)果,那么如何在兩種模式下都能得到我們期盼的結(jié)果呢。我們可以如下操作。

正確的代碼:

class Program  {    static void Main(string[] args)    {      Timer timer = new Timer(TimerCallback,null,0,2000);          Console.ReadLine();      timer.Dispose();    }    private static void TimerCallback(object o)    {      Console.WriteLine("in TimerCallback method");      GC.Collect();          }  }

這時不管是在release模式下還是debug模式下,都會每隔2秒鐘調(diào)用我們的回調(diào)方法。



注:相關(guān)教程知識閱讀請移步到c#教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 河西区| 茶陵县| 富源县| 梁山县| 阿克陶县| 清新县| 澄迈县| 乳山市| 巩留县| 吴旗县| 丰城市| 化州市| 廊坊市| 鹿泉市| 巴彦县| 农安县| 大宁县| 沈阳市| 五莲县| 金堂县| 朝阳市| 松原市| 镶黄旗| 阆中市| 垣曲县| 六安市| 墨脱县| 海南省| 富蕴县| 应城市| 湟源县| 舞钢市| 米林县| 泸定县| 大邑县| 睢宁县| 壤塘县| 阜宁县| 洪江市| 玛多县| 乌审旗|