views:

69

answers:

1

I am using the EventAgregator pattern to subscribe and publish events. If a user subscribes to the event using a lambda expression, they must use a strong reference, not a weak reference, otherwise the expression can be garbage collected before the publish will execute.

I wanted to add a simple check in the DelegateReference so that if a programmer passes in a lambda expression and is using a weak reference, that I throw an argument exception. This is to help "police" the code.

Example:

eventAggregator.GetEvent<RuleScheduler.JobExecutedEvent>().Subscribe
        (
            e => resetEvent.Set(),
            ThreadOption.PublisherThread,
            false,
            // filter event, only interested in the job that this object started
            e => e.Value1.JobDetail.Name == jobName
        );


public DelegateReference(Delegate @delegate, bool keepReferenceAlive)
    {
        if (@delegate == null)
            throw new ArgumentNullException("delegate");

        if (keepReferenceAlive)
        {
            this._delegate = @delegate;
        }
        else
        {
            //TODO: throw exception if target is a lambda expression
            _weakReference = new WeakReference(@delegate.Target);
            _method = @delegate.Method;
            _delegateType = @delegate.GetType();
        }
    }

any ideas? I thought I could check for @delegate.Method.IsStatic but I don't believe that works... (is every lambda expression a static?)

+1  A: 

No, not every lambda-generated delegate is a static method. If there are captured variables it can be an instance. But ultimately there is very little difference between a lambda- based delegate, an anonymous-method- based delegate, and an explicit delegate. I wouldn't do any additional logic - just treat it as a delegate (I would remove the WeakReference code completely).

Marc Gravell
so there is now way to tell if a delegate is anonymous? Personally, I don't particular like the WeakReference code because after your class lifetime is over, if you don't unsubscribe, your method can be getting called in the background repeatedly (or at least the filter method). But such is the microsoft "Best Practices". :)I believe that silverlight, which uses this pattern, will throw an exception if you try to use a weak reference with an anonymous delegate... so I thought it should be do-able.
Keith
@Keith - I would be surprised if a `new` was optimised away.
Marc Gravell