WeakAction question

May 20, 2011 at 11:46 AM

Hi Laurent,

My be I'm wrong, but what if we have in the action (used in a WeakAction) a strong reference to the action's owner (for example in the action's code we have something like this.member). Will we have then a strong reference to the target (through the action) that will keep the it away from the GC? So, I think it's better to use a WeakReference and to the action.

Thank you!

May 20, 2011 at 3:49 PM
Edited May 20, 2011 at 3:53 PM

FYI, this issue came up in the context of discussing messenger here so I believe Laurent is aware of it.

When I last took a look at MVVM Light I posted a discussion of some possible solutions to the weak action problem here, feel free to use the solutions I suggested there if you wish.

Curt

 

Coordinator
Jun 2, 2011 at 12:49 PM
Edited Jun 2, 2011 at 12:50 PM

Curt, FWIW unfortunately your proposed solution will not work on SL/WP7 due to the restrictions on the CreateDelegate method. In consequence I am rather going to follow the approach described here:

http://blog.tonysneed.com/2011/03/22/building-a-leak-proof-eventing-model/

Cheers,

Laurent

Jun 7, 2011 at 5:09 PM

Hey Laurent, that seems a reasonable approach.

Curt

 

Jun 9, 2011 at 9:04 PM

Am I missing something or can you not just change WeakAction to have WeakReference to the Action?

My simple below seems to suggest it would work

    public class ClassToGc
    {
        int i = 0;

        public void AnAction()
        {
            Console.WriteLine("foo");
        }
    }
    class Program
    {

        static void Main(string[] args)
        {
            ClassToGc gcer = new ClassToGc();

            WeakReference refer = new WeakReference(gcer);

            Action act = gcer.AnAction;

            WeakReference actreferr = new WeakReference(act);            

            Console.WriteLine(refer.IsAlive);

            gcer = null;
            act = null;
                        
            
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            GC.WaitForPendingFinalizers();

            Console.WriteLine(refer.IsAlive);
        }
    }

 

Jun 9, 2011 at 9:52 PM

Yes Musmuris,

But if you nullify only 'act', but not 'gcer', then after garbage collection 'refer' will be still alive, but not 'actreferr'. So the target may be still alive and waiting for notifications but notification action couldn't be executed.

Jun 9, 2011 at 10:18 PM

Ah yes... that's the bit I would be missing then!