成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

C#中如何解決定時器?;顧C(jī)制引起的內(nèi)存泄露問題

這篇文章主要介紹C#中如何解決定時器?;顧C(jī)制引起的內(nèi)存泄露問題,文中介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們一定要看完!

創(chuàng)新互聯(lián)公司是一家專注于做網(wǎng)站、網(wǎng)站建設(shè)與策劃設(shè)計(jì),武定網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:武定等地區(qū)。武定做網(wǎng)站價格咨詢:18982081108

C# 中有三種定時器,System.Windows.Forms 中的定時器和 System.Timers.Timer 的工作方式是完全一樣的,所以,這里我們僅討論 System.Timers.Timer 和 System.Threading.Timer

1、定時器?;?/strong>

先來看一個例子:

class Program
{
  static void Main(string[] args)
  {
    Start();

    GC.Collect();
    Read();
  }

  static void Start()
  {
    Foo f = new Foo();
    System.Threading.Thread.Sleep(5_000);
  }
}

public class Foo
{
  System.Timers.Timer _timer;

  public Foo()
  {
    _timer = new System.Timers.Timer(1000);
    _timer.Elapsed += timer_Elapsed;
    _timer.Start();
  }

  private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
  {
    WriteLine("System.Timers.Timer Elapsed.");
  }
  
  ~Foo()
  {
    WriteLine("---------- End ----------");
  }
}

運(yùn)行結(jié)果如下:

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 方法結(jié)束后,F(xiàn)oo 實(shí)例已經(jīng)失去了作用域,按理說應(yīng)該被回收,但實(shí)際并沒有(因?yàn)槲鰳?gòu)函數(shù)沒有執(zhí)行,所以肯定實(shí)例未被回收)。

這就是定時器的 ?;顧C(jī)制,因?yàn)槎〞r器需要執(zhí)行 timer_Elapsed 方法,而該方法屬于 Foo 實(shí)例,所以 Foo 實(shí)例被?;盍恕?/p>

但多數(shù)時候這并不是我們想要的結(jié)果,這種結(jié)果導(dǎo)致的結(jié)果就是 內(nèi)存泄露,解決方案是:先將定時器 Dispose。

public class Foo : IDisposable
{
  ...
  public void Dispose()
  {
    _timer.Dispose();
  }
}

一個很好的準(zhǔn)則是:如果類中的任何字段所賦的對象實(shí)現(xiàn)了IDisposable 接口,那么該類也應(yīng)當(dāng)實(shí)現(xiàn) IDisposable 接口。

在這個例子中,不止 Dispose 方法,Stop 方法和設(shè)置 AutoReset = false,都能起到釋放對象的目的。但是如果在 Stop 方法之后又調(diào)用了 Start 方法,那么對象依然會被?;睿幢?Stop 之后進(jìn)行強(qiáng)制垃圾回收,也無法回收對象。

System.Timers.Timer System.Threading.Timer 的?;顧C(jī)制是類似的。

?;顧C(jī)制是由于定時器引用了實(shí)例中的方法,那么,如果定時器不引用實(shí)例中的方法呢?

2、不保活下 System.Timers.Timer 和 System.Threading.Timer 的差異

要消除定時器對實(shí)例方法的引用也很簡單,將 timer_Elapsed 方法改成 靜態(tài) 的就好了。(靜態(tài)方法屬于類而非實(shí)例。)

改成靜態(tài)方法后再次運(yùn)行示例,結(jié)果如下:

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 實(shí)例是被銷毀了(析構(gòu)函數(shù)已運(yùn)行,打印出了 End),但定時器還在執(zhí)行,這是為什么呢?

這是因?yàn)椋?NET Framework 會確保 System.Timers.Timer 的存活,即便其所屬實(shí)例已經(jīng)被銷毀回收。

如果改成 System.Threading.Timer,又會如何?

class Program
{
  static void Main(string[] args)
  {
    Start();

    GC.Collect();
    Read();
  }

  static void Start()
  {
    Foo2 f2 = new Foo2();
    System.Threading.Thread.Sleep(5_000);
  }
}

public class Foo2
{
  System.Threading.Timer _timer;

  public Foo2()
  {
    _timer = new System.Threading.Timer(timerTick, null, 0, 1000);
  }

  static void timerTick(object state)
  {
    WriteLine("System.Threading.Timer Elapsed.");
  }

  ~Foo2()
  {
    WriteLine("---------- End ----------");
  }
}

注意,這里的 timerTick 方法是靜態(tài)的。運(yùn)行結(jié)果如下:

System.Threading.Timer Elapsed.
System.Threading.Timer Elapsed.
System.Threading.Timer Elapsed.
System.Threading.Timer Elapsed.
System.Threading.Timer Elapsed.
---------- End ----------

可見,隨著 Foo2 實(shí)例銷毀,_timer 也自動停止并銷毀了。

這是因?yàn)椋?NET Framework 不會保存激活 System.Threading.Timer 的引用,而是直接引用回調(diào)委托。

以上是“C#中如何解決定時器?;顧C(jī)制引起的內(nèi)存泄露問題”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

當(dāng)前標(biāo)題:C#中如何解決定時器?;顧C(jī)制引起的內(nèi)存泄露問題
網(wǎng)頁網(wǎng)址:http://jinyejixie.com/article2/igopic.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、企業(yè)網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、動態(tài)網(wǎng)站、Google、品牌網(wǎng)站設(shè)計(jì)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

楚雄市| 麻江县| 改则县| 章丘市| 元阳县| 祥云县| 略阳县| 吉木萨尔县| 墨脱县| 柏乡县| 托克逊县| 原平市| 秦皇岛市| 正蓝旗| 平塘县| 大悟县| 阿拉善盟| 翁牛特旗| 永福县| 霍林郭勒市| 松原市| 县级市| 龙游县| 仪陇县| 沽源县| 泗水县| 洛浦县| 临汾市| 定南县| 永仁县| 保康县| 始兴县| 会同县| 宜宾县| 永新县| 亳州市| 武平县| 杭锦后旗| 泰兴市| 克什克腾旗| 平度市|