1

Closed

Caliburn.Micro framework crash due to ActionMessage

description

Caliburn.Micro framework will crash randomly in my application due to ActionMessage.

I found in ActionMessage.cs, there is a action called SetMethodBinding. The crashes come out randomly (expecially when CPU usage is high and memory is low) due to context.Source inside that action become null, which will definitely cause exception.

I also found the Source is weakReference. Does it mean it get posibility that GC will reclaim Source whenever memory is low, which is the key point of this issue.

Is there any ways to avoid these crashes?
Closed Sep 2, 2013 at 4:32 AM by EisenbergEffect
Fixed.

comments

BladeWise wrote Jul 19, 2013 at 10:06 AM

There are a bit of checks that are probably missing, causing an odd behaviour when the source is reclaimed by the GC.
To stay on the safe side, it would be better to retrieve the context.Source value on a local variable and use it, instead of retrieving the value directly from the weak reference.

Anyway, there is a high chance that this is the faulty code:
if (context.Source.DataContext != null) {
                var target = context.Source.DataContext;
                var method = GetTargetMethod(context.Message, target);

                if (method != null) {
                    context.Target = target;
                    context.Method = method;
                    context.View = context.Source;
                }
            }
It would be better to do something like this, instead:
var source = context.Source;
object dataContext;
if (source != null && (dataContext = source.DataContext) != null) {
                var target = dataContext;
                var method = GetTargetMethod(context.Message, target);

                if (method != null) {
                    context.Target = target;
                    context.Method = method;
                    context.View = source;
                }
            }
Since the SetMethodBinding is an extension point, try to replace the default implementation with a more robust one (along the lines of the above code), and test if the problem still occurs.