你需要知道的c# Timer 的記憶體回收機制。

來源:互聯網
上載者:User

標籤:

通常我們需要定時執行一段任務的時候,我們就需要定時器,這時我們就可以使用c# System.Threading空間中的 Timer定時器;他是個非同步定時器,時間到時每次都是線上程池中分配一個線程去執行任務。下面我們來看一個有趣的例子:

 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秒鐘執行該方法,列印出"in TimerCallback method”,而在release模式下執行的時候,只執行一次該方法,字串只列印一次。在這裡我們在調用TimerCallback方法時,強制執行記憶體回收行程,說明在release模式下,記憶體回收行程執行回收演算法時,首先假設所有對象都是可回收的,當將Timer對象賦值給變數t後,t沒有在被引用,因此也就沒有變數引用Timer對象,所以垃圾收集這時會回收Timer對象。那麼為什麼在debug模式下卻能夠運行能,這跟c#編譯器的最佳化方式有關,在release模式下編譯器做了相關的最佳化操作。而在debug模式下,timer對象的產生期是方法的結束,這樣做也是為了調試的方便。要不然在調試時,我們執行到Timer timer = new Timer()後想看timer的值時,已經被記憶體回收行程給回收了,這是我們不期望看到的結果,編譯器如何處理的,我們可以看看編譯器在release模式下和debug模式下對上面的代碼編譯後產生的IL對比我們既知結果。

release模式編譯產生的IL:

 

 1 .method private hidebysig static void  Main(string[] args) cil managed 2 { 3   .entrypoint 4   // Code size       32 (0x20) 5   .maxstack  8 6   IL_0000:  ldnull 7   IL_0001:  ldftn      void GCTest.Program::TimerCallback(object) 8   IL_0007:  newobj     instance void [mscorlib]System.Threading.TimerCallback::.ctor(object, 9                                                                                      native int)10   IL_000c:  ldnull11   IL_000d:  ldc.i4.012   IL_000e:  ldc.i4     0x7d013   IL_0013:  newobj     instance void [mscorlib]System.Threading.Timer::.ctor(class [mscorlib]System.Threading.TimerCallback,14                                                                              object,15                                                                              int32,16                                                                              int32)17   IL_0018:  pop18   IL_0019:  call       string [mscorlib]System.Console::ReadLine()19   IL_001e:  pop20   IL_001f:  ret21 } // end of method Program::Main

 

debug模式下產生的IL:

 1 method private hidebysig static void  Main(string[] args) cil managed 2 { 3   .entrypoint 4   // Code size       33 (0x21) 5   .maxstack  4 6   .locals init ([0] class [mscorlib]System.Threading.Timer timer) 7   IL_0000:  nop 8   IL_0001:  ldnull 9   IL_0002:  ldftn      void GCTest.Program::TimerCallback(object)10   IL_0008:  newobj     instance void [mscorlib]System.Threading.TimerCallback::.ctor(object,11                                                                                      native int)12   IL_000d:  ldnull13   IL_000e:  ldc.i4.014   IL_000f:  ldc.i4     0x7d015   IL_0014:  newobj     instance void [mscorlib]System.Threading.Timer::.ctor(class [mscorlib]System.Threading.TimerCallback,16                                                                              object,17                                                                              int32,18                                                                              int32)19   IL_0019:  stloc.020   IL_001a:  call       string [mscorlib]System.Console::ReadLine()21   IL_001f:  pop22   IL_0020:  ret23 } // end of method Program::Main

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

正確的代碼:

 1   class Program 2     { 3         static void Main(string[] args) 4         { 5             Timer timer = new Timer(TimerCallback,null,0,2000); 6          7             Console.ReadLine(); 8             timer.Dispose(); 9         }10 11         private static void TimerCallback(object o)12         {13             Console.WriteLine("in TimerCallback method");14 15             GC.Collect();16 17             18         }19     }

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

 

你需要知道的c# Timer 的記憶體回收機制。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.