2016-12-28 2 views
1

Ich versuche Dinge mit schwachen Referenzen in vs2015 und hier ist ein Beispiel, wo ich nicht verstehe, warum ist die schwache Referenz der Action-Instanz, die ich am Ende erstellt vollständig verloren?WeakReference in C# - Wie ist die Action-Instanz verloren gegangen?

Könnt ihr mir bei diesem Problem helfen?

Hier ist die Code-und Invoke-Methode aint aufrufen, da die Aktion an diesem Punkt Nullwert hat. Aber es sollte keinen Nullwert haben.

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

Ich hätte erwartet, dass ... Ihre einzige Referenz auf das Objekt ist eine schwache Referenz und Sie rufen GC sammeln. Der MSDN-Status "Repräsentiert eine schwache Referenz, die auf ein Objekt verweist, während das Objekt weiterhin von der Garbage Collection zurückgewonnen werden kann". Sie benötigen immer noch eine Referenz, um sie vor der Sammlung zu schützen. Ich glaube, dass dies die Absicht hat, vorübergehende Objekthalteverweise auf geteilte Ressourcen zuzulassen. – Jonathan

+1

Ihr Codebeispiel sollte minimalistisch sein und nur Code enthalten, der für die Frage relevant ist. – Phil1970

+0

Ich habe meinen Code geändert, bitte sieh ihn dir an und sag mir, warum die Action verloren geht? –

Antwort

4

GC verwendet Wurzeln der Marke Phase der Garbage Collection zu starten. In Ihrem Beispielcode sind die einzigen relevanten Wurzeln die lokalen Variablen der Methode, die beim Start der Sammlung ausgeführt werden. Es gibt keine anderen statischen Felder oder ähnliches. Und von dort ist die WeakReference die einzige Möglichkeit, die Action erreicht werden kann. Aus diesem Grunde ist für die Sammlung geeignet (das ist der wesentliche Punkt der WeakReference):

eine schwache Referenz darstellt, die ein Objekt referenziert, während immer noch ermöglicht, dass das Objekt von der Garbage Collection freigegeben werden.

Wenn Sie Garbage Collection erzwingen, wird es zurückgefordert und Sie können mich nicht mehr anrufen.

+0

Ich habe meinen Code geändert. Bitte schauen Sie und sagen Sie mir, was ich hier mit schwachen Referenzen vermisse. Danke –

Verwandte Themen