Question Action C #, fermeture et collecte de déchets


Dois-je définir MyAction sur null pour que la récupération de place puisse continuer avec l'une de ces classes?

Je suis moins préoccupé lorsque les deux classes ont presque la même durée de vie. Ma question est plus appropriée lorsque la durée de vie de Class1 est beaucoup plus longue que celle de Class2 ou lorsque la durée de vie de Class2 est beaucoup plus longue que celle de Class1.

Le code ici est réduit. Supposons que Class1 et Class2 contiennent d'autres membres et des méthodes susceptibles d'affecter leur durée de vie.

public class Class1 : IDisposable
{
    public Action<string> MyAction { get; set; }

    // Is this necessary?
    public void Dispose()
    {
        MyAction = null;
    }
}

public class Class2
{
    string _result = string.Empty;

    public void DoSomething()
    {
        Class1 myClass1 = new Class1();
        myClass1.MyAction = s => _result = s;
        myClass1.Dispose();
    }
}

14
2017-11-17 16:28


origine


Réponses:


Dois-je définir MyAction sur null pour que la récupération de place puisse continuer avec l'une de ces classes?

Non. Chaque fois que vous "supprimez" une ressource gérée, les chances sont bonnes que vous le fassiez mal. Laissez le ramasse-miettes faire son travail.

Je suis moins préoccupé lorsque les deux classes ont presque la même durée de vie. Ma question est plus appropriée lorsque la durée de vie de Class1 est beaucoup plus longue que celle de Class2 ou lorsque la durée de vie de Class2 est beaucoup plus longue que celle de Class1.

La question n'a pas de sens. Des classes n'ai pas durées de vie. Les emplacements de stockage ont une durée de vie. Précisément quels sont les emplacements de stockage qui vous inquiètent? Pouvez-vous clarifier la question?

Je constate qu'il existe de très sérieuses préoccupations quant à la prolongation de la durée de vie des variables fermées via des fermetures; Votre question est cependant si vague qu'il est difficile de comprendre si vous vous trouvez dans une telle situation. Permettez-moi de démontrer:

class Expensive
{
    public byte[] huge = MakeHugeByteArray();
}

class Cheap
{
    public int tiny;
}

class C
{
    public static Func<Cheap> longLived;
    public static void M()
    { 
        Expensive expensiveLocal = new Expensive();
        Cheap cheapLocal = new Cheap();
        Func<Expensive> shortLived = ()=>expensiveLocal ;
        C.longLived = ()=>cheapLocal;
    }
}

Quelle est la durée de vie de la variable locale chèreLocal? La durée de vie d'une variable locale est généralement court; En général, les variables locales ne sont plus activées par la méthode. cependant, être dans une fermeture prolonge la durée de vie d'une variable locale de manière arbitraire, jusqu'à la durée de la fermeture. Dans ce cas particulier, les deux lambdas partager une fermeture, et cela signifie que la durée de vie de la variable localehernLocal est au moins aussi longue que la durée de vie de la variable locale cheapLocal, qui a une durée de vie indéfiniment longue car une référence à la fermeture vient d'être stockée dans un champ statique qui vit pour toujours. Ce grand tableau d'octets pourrait jamais être récupéré, même si la seule chose qui semble le faire référence a été recueillie depuis longtemps; la fermeture est une référence cachée.

De nombreuses langues ont ce problème; C #, VB, JScript et ainsi de suite ont tous des fermetures lexicales qui ne sont pas partitionnées pour regrouper les variables par durée de vie. Nous envisageons de changer C # et VB pour avoir une meilleure gestion de la durée de vie des fermetures, mais cela reste un travail très futur, donc aucune garantie.


18
2017-11-17 17:16



Non, il n'est pas nécessaire de définir la référence sur null.

Dispose() est pour le nettoyage des ressources non gérées. Action<string> est une ressource gérée et sera correctement gérée par le CLR lorsque l'instance de Class1 tombe hors de portée à la fin de DoSomething().


4
2017-11-17 16:30



Non, vous ne le faites pas. Le ramasse-miettes va le gérer.


0
2017-11-17 16:31



Une fois le Faire quelque chose résultats, myCLass1 est un candidat pour le ramassage des ordures. Lorsqu'une classe est collectée, tous ses membres sont également collectés s'il n'y a pas de références en suspens. Vous n'avez donc pas besoin de faire ce que vous faites


0
2017-11-17 16:32