2016-12-28 39 views
1

我想在vs2015中引用弱點,這裏是一個例子,我不明白爲什麼我最終創建的動作實例的弱引用完全丟失了?C#中的WeakReference - 動作實例如何丟失?

你們可以幫我解決這個問題嗎?

下面是代碼和調用方法調用,因爲該操作具有空值。但它不應該有空值。

class Program 
{ 
    static void Main(string[] args) 
    { 
     Class2 c1 = new Class2(); 
     Class4 c4 = new Class4(); 
     Class3 c3 = new Class3(); 
     c4.AssignActionA(c3, c4.CreateAction(c1)); 
     c4.AssignActionB(c3, c4.CreateAction(c1)); 
     GC.Collect(); 

     Class5 c5 = new Class5(); 
     c5.CallActionA(c3); 
     c5.CallActionB(c3); 

     //Task.Run(() => 
     //{ 
     // Class5 c5 = new Class5(); 
     // c5.CallAction(c3);  
     //}); 

     Console.ReadLine(); 
    } 
} 

public class Class5 
{ 
    public void CallActionA(Class3 c3) 
    { 
     Action a; 
     c3.A.TryGetTarget(out a); 
     a?.Invoke(); 
    } 

    public void CallActionB(Class3 c3) 
    { 
     c3.B(); 
    } 
} 

public class Class4 
{ 
    public Action CreateAction(Class2 c1) 
    { 
     //Class1 c1 = new Class1(); 
     Action a =() => 
     { 
      var temp = c1; 
     }; 

     return a; 
    } 

    public void AssignActionA(Class3 c3, Action a) 
    { 
     c3.A = new WeakReference<Action>(a); 
    } 

    public void AssignActionB(Class3 c3, Action b) 
    { 
     c3.B = b; 
    } 
} 

public class Class2 
{ 
} 

public class Class3 
{ 
    public WeakReference<Action> A { get; set; } 
    public Action B { get; set; } 
} 
+1

我會期待......你對對象的唯一引用是一個弱引用,你稱之爲gc collect。 MSDN指出「代表弱引用,它引用了一個對象,同時仍然允許該對象被垃圾回收回收」。你仍然需要一個參考來保護它免受收集。我相信這樣做的目的是允許暫存對象保持對共享資源的引用。 – Jonathan

+1

您的代碼示例應該是極簡主義的,並且只包含與問題相關的代碼。 – Phil1970

+0

我改變了我的代碼,請看看並告訴我爲什麼動作會丟失? –

回答

4

GC採用根部開始垃圾收集馬克階段。在示例代碼中,唯一重要的根是收集開始時正在執行的方法的局部變量。沒有其他的靜態字段或類似的東西。從那裏,WeakReferenceAction可以達到的唯一途徑。因爲這是符合回收(這就是WeakReference整點):

表示弱引用,它引用的對象,同時還允許該對象被垃圾收集回收。

當你強制垃圾收集它被收回,你不能再打電話給我。

+0

我改變了我的代碼。請看看,並告訴我我在這裏用弱引用丟失了什麼。謝謝 –