不能使目标保持活动的代表

时间:2019-06-19 15:00:44

标签: c# garbage-collection delegates

有没有一种方法可以防止代表使目标保持活动状态?

如果我有Action a = someObj.DoSomething,则someObj将由代表保留。

如果我有WeakReference<Action> a = new WeakReference<Action>((Action)someObj.DoSomething),则someObj仍将由代理保持活动状态,但是GC会收集委托本身,然后可以收集目标。

2 个答案:

答案 0 :(得分:1)

您只想拥有一个使用的弱引用,而不是弱引用的委托。

WeakReference<YourObjectType> someObjReference = new WeakReference<YourObjectType>(someObj);
Action a = () =>
{
    if (someObjReference.TryGetTarget(out YourObjectType someObjValue))
        someObjValue.DoSomething();
};

答案 1 :(得分:-1)

我认为您所做的是正确的,还有其他事情使您感到反对。

我正在测试

    class Program
    {
        public class YourObjectType {
            public void DoSomething() { }
        }
        public class WeakReferences {
            public WeakReference<Action> a;
            public WeakReference<YourObjectType> o;
        }

        static WeakReferences createReferences() {
            var someObj = new YourObjectType();

            return new WeakReferences() { a = new WeakReference<Action>((Action)someObj.DoSomething), o = new WeakReference<YourObjectType>(someObj) };
        }

        static void Main(string[] args)
        {
            WeakReferences wr = createReferences();
            YourObjectType o = null;
            wr.o.TryGetTarget(out o); //comment this line to collect it instead
            GC.Collect();
            Action a = null;

            Console.WriteLine(wr.a.TryGetTarget(out a));
            Console.WriteLine(wr.o.TryGetTarget(out o));
            Console.ReadLine();
        }
    }

实际上,如果您避免使用第一个TryGetTarget,它将消失。