簡體   English   中英

奇怪的析構函數行為,調用兩次,但第一次跳過代碼執行

[英]Strange destructor behavior, called twice, but skip code execution for the first time

為了簡化事情,假設我在析構函數里面有簡單的類定義

public class MyDisposeFinalize
{
    ~MyDisposeFinalize()
    {
        var breakPoint = string.Empty;
    }
}

Main方法中,我首先創建MyDisposeFinalize類的實例,然后將null賦給我的實例並調用垃圾回收。

    static void Main(string[] args)
    {
        var myDispose = new MyDisposeFinalize();
        myDispose = null;
        GC.Collect();

        System.Console.ReadKey();
    }

我希望我的析構函數會被調用一次,當終結線程進程終結隊列時。

事實上,當我在我的析構函數方法中輸入斷點,在內部和退出時,我有非常奇怪的行為:

  1. 進入破發點被擊中
  2. 然后再次進入破發點
  3. 內線突破點被擊中
  4. 退出破發點被擊中
  5. 然后再次進入破發點

第一個想法是兩個不同的線程來執行析構函數方法,但是為什么其中一個跳過方法代碼並且只在第二次迭代時執行它? 一般來說為什么desctructor被調用兩次?

如果您在ILSpy中打開代碼,您會看到:

protected override void Finalize()
{
    try
    {
        string breakPoint = string.Empty;
    }
    finally
    {
        base.Finalize();
    }
}

我希望通過打開開括號和閉括號,你會看到多行'代碼'正在執行,這些代碼行與打開和關閉大括號相關聯的代碼行相關聯。 trybase.Finalize()調用。

在原始IL中,代碼的結尾部分如下所示:

finally
{
    IL_000a: ldarg.0
    IL_000b: call instance void [mscorlib]System.Object::Finalize()
    IL_0010: nop
    IL_0011: endfinally
} //

它調用Object :: Finalize(),這可能是斷點第二次停止的地方。

我不確定在那里設置斷點的預期行為是什么,但我認為這是你所看到的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM