最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# 定時器保活機制引起的內(nèi)存泄露問題解決

 更新時間:2020年02月12日 11:32:52   作者:丹楓無跡  
這篇文章主要介紹了C# 定時器?;顧C制引起的內(nèi)存泄露問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

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

1、定時器保活

先來看一個例子:

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 ----------");
  }
}

運行結(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 實例已經(jīng)失去了作用域,按理說應(yīng)該被回收,但實際并沒有(因為析構(gòu)函數(shù)沒有執(zhí)行,所以肯定實例未被回收)。

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

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

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

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

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

System.Timers.Timer System.Threading.Timer 的?;顧C制是類似的。

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

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

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

改成靜態(tài)方法后再次運行示例,結(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 實例是被銷毀了(析構(gòu)函數(shù)已運行,打印出了 End),但定時器還在執(zhí)行,這是為什么呢?

這是因為,.NET Framework 會確保 System.Timers.Timer 的存活,即便其所屬實例已經(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)的。運行結(jié)果如下:

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 的引用,而是直接引用回調(diào)委托。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C#中DataTable 轉(zhuǎn)換為 Json的方法匯總(三種方法)

    C#中DataTable 轉(zhuǎn)換為 Json的方法匯總(三種方法)

    JavaScript Object Notation (Json)是一種輕量級的數(shù)據(jù)交換格式,下面小編給大家介紹三種方法實現(xiàn)DataTable轉(zhuǎn)換成 Json 對象,感興趣的朋友一起看看吧
    2016-11-11
  • C# 中使用NModbus4通信庫執(zhí)行寫操作

    C# 中使用NModbus4通信庫執(zhí)行寫操作

    在C#中NModbus4庫提供了一個方便的方式來與支持Modbus協(xié)議的設(shè)備進行交互,本文就來介紹了使用NModbus4通信庫執(zhí)行寫操作,具有一定的參考價值,感興趣的可以了解一下
    2024-03-03
  • C#中AutoResetEvent控制線程用法小結(jié)

    C#中AutoResetEvent控制線程用法小結(jié)

    本文主要來自一道面試題,由于之前對AutoResetEvent的概念比較模糊,面試題題目很簡潔:兩個線程交替打印0~100的奇偶數(shù),你可以先動手試試,我主要是嘗試在一個方法里面完成這個任務(wù),需要的朋友可以參考下
    2022-07-07
  • C# 關(guān)于AppDomain的一些總結(jié)

    C# 關(guān)于AppDomain的一些總結(jié)

    這篇文章主要介紹了C# 關(guān)于AppDomain的一些總結(jié),幫助大家更好的理解和使用c#,感興趣的朋友可以了解下
    2021-02-02
  • C#正則表達式實用大全(建議收藏!)

    C#正則表達式實用大全(建議收藏!)

    正則表達式是處理字符串的強大工具,擁有獨特的語法和獨立的處理引擎,下面這篇文章主要給大家介紹了關(guān)于C#正則表達式實用大全的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • C#對集合進行排序

    C#對集合進行排序

    這篇文章介紹了C#對集合進行排序的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-03-03
  • C#并行編程Task類用法介紹

    C#并行編程Task類用法介紹

    這篇文章介紹了C#并行編程Task類的用法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • WPF 自定義雷達圖開發(fā)實例教程

    WPF 自定義雷達圖開發(fā)實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發(fā)實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下
    2016-09-09
  • C#飛行棋小程序設(shè)計分析

    C#飛行棋小程序設(shè)計分析

    這篇文章主要為大家設(shè)計分析了C#飛行棋小程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 詳解C#中委托的概念與使用

    詳解C#中委托的概念與使用

    委托這個名字取的神乎其神的,但實質(zhì)是函數(shù)式編程,把函數(shù)作為參數(shù)傳遞給另一個參數(shù)。這篇文章主要為大家介紹一下C#中委托的概念與使用,需要的可以參考一下
    2023-02-02

最新評論

阿拉尔市| 万宁市| 古交市| 湖南省| 特克斯县| 休宁县| 达拉特旗| 延庆县| 固始县| 修水县| 太仆寺旗| 道孚县| 乌拉特后旗| 乌什县| 连江县| 利川市| 白水县| 伊春市| 汕头市| 夏河县| 赞皇县| 文成县| 新建县| 大荔县| 曲麻莱县| 栾城县| 台北县| 个旧市| 平果县| 广水市| 东兰县| 通榆县| 兴和县| 阆中市| 全椒县| 通道| 五家渠市| 会理县| 双峰县| 阜城县| 秭归县|