程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> 詳解C#中的准時器Timer類及其渣滓收受接管機制

詳解C#中的准時器Timer類及其渣滓收受接管機制

編輯:C#入門知識

詳解C#中的准時器Timer類及其渣滓收受接管機制。本站提示廣大學習愛好者:(詳解C#中的准時器Timer類及其渣滓收受接管機制)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解C#中的准時器Timer類及其渣滓收受接管機制正文


關於C# Timer類  在C#裡關於准時器類就有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

運用於WinForm中的,它是經由過程Windows新聞機制完成的,相似於VB或Delphi中的Timer控件,外部應用API  SetTimer完成的。它的重要缺陷是計時不准確,並且必需有新聞輪回,Console  Application(掌握台運用法式)沒法應用。  
 
(2)System.Timers.Timer

和System.Threading.Timer異常相似,它們是經由過程.NET  Thread  Pool完成的,輕量,計時准確,對運用法式、新聞沒有特殊的請求。

(3)System.Timers.Timer還可以運用於WinForm,完整代替下面的Timer控件。它們的缺陷是不支撐直接的拖放,須要手工編碼。

C# Timer用法實例

應用System.Timers.Timer類

System.Timers.Timer t =  
new System.Timers.Timer(10000); 
//實例化Timer類,設置距離時光為10000毫秒;  
t.Elapsed +=  
new System.Timers.ElapsedEventHandler(theout); 
//達到時光的時刻履行事宜;  
t.AutoReset = true; 
//設置是履行一次(false)照樣一向履行(true);  
t.Enabled = true; 
//能否履行System.Timers.Timer.Elapsed事宜;  
 
public void theout( 
object source,  
System.Timers.ElapsedEventArgs e)  
 {  
  MessageBox.Show("OK!");  
 } 

 
Timer的渣滓收受接管機制
平日我們須要准時履行一段義務的時刻,我們就須要准時器,這時候我們便可以應用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:

.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對象,所以也能湧現我們期盼的成果,那末若何在兩種形式下都能獲得我們期盼的成果呢。我們可以以下操作。

准確的代碼:

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秒鐘挪用我們的回調辦法。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved