How to raise weak events? - c#

I'm reading the MS docs on how to implement the weak event pattern. I've tried the first two (since I'm looking for the simplest way) but I can't find a way to raise the event.
The existing weak event managers like the PropertyChangedEventManager, and the generic WeakEventManager only have methods to add and remove handlers but nothing to raise the event. Also, I can't inherit those it says [the base class] does not contain a constructor that takes 0 arguments (the constructors are private).
So I'm finding the docs confusing - how are these constituted the ways to implement the weak event pattern if there's no way to raise the event?
If the suggested way in the docs doesn't work I'm looking for the simplest way to raise and handle weak events.

Related

Is having default event initializer considered a good practice?

One thing that I find slightly annoying is having to null-check events. An event that has no subscribers is going to be null, so often times code like this has to be written:
MyEvent?.Invoke()
One solution for this problem I've found was this initialization pattern, where we initialize event with a no-op delegate:
public event Action MyEvent = delegate { };
Now, since this event is always going to have at least one dummy subscriber, we no longer have to check for null:
MyEvent.Invoke()
While this is pretty convenient, I was wondering whether this pattern a good practice, or is there some reason that I don't see that would make this a bad decision (aside from having to call an extra dummy subscriber, but I am fine with that)? Thanks.

How to make a fakeable event

What is the proper way to raise an event using MOQ? I am currently setting the event as virtual and using the Raise method. The problem I am currently posed with is that R# yells
Invocation of polymorphic field-like event
I am not a huge fan of creating an interface for one implementation, so I default to virtual first. Is making this an interface my only workaround?
After further discussion with a coworker, I think that an interface is required here. My SUT is verifying the result after the event, which is being faked...so there is no OnEvent method implementation. Nor should my SUT care about that implementation...only that the event was raised. So....unless I hear a compelling reason otherwise, this is a case where I go with the interface option.

What to do with IObservers being disposed?

I'm using Reactive Extensions for easy event handling in my ViewModels (Silverlight and/or Wp7 apps). For sake of simplicity let's say I have a line like this in the ctor of my VM:
Observable.FromEvent<PropertyChangedEventArgs>(
h => MyObject.PropertyChanged += h,
h => MyObject.PropertyChanged -= h)
.Where(e=>e.PropertyName == "Title")
.Throttle(TimeSpan.FromSeconds(0.5))
.Subscribe(e=>{/*do something*/});
this returns an IDisposable object, which if disposed will unsubscribe. (Am I right in this assumption?)
If I hold no reference to it, sooner or later it will be collected, and my handler will be unsubscribed.
I usually have a List<IDisposable> in my VM, and I add subscriptions to it, yet I feel dirty about it, as if I'm not doing something in a correct Rx way.
What is the best practice, recommended pattern on situations like this?
Your first assumption is correct, the IDisposable is for unsubscribing. However, you do not need to hold a reference to the IDisposable to prevent your observer from being collected. The IObservable will need to keep a reference to the observer to be able to call its methods, thus keeping the observer alive as long as the observable is alive.
The astute reader will realize that I am somewhat begging the question, because I have assumed that the observable will not be collected. To deal with that issue, let's make some reasonable guesses about what's going on behind the scenes. The first observable is subscribing to an event. This means that the object with the event has a reference to our observer from the time we subscribe to the time we unsubscribe. Since Rx operators must at some point subscribe to their sources, one can assume that the event observer has a reference to the Where observer, which has a reference to the Throttle observer, which of course is referring to our final observer.
Since we kept no way to unsubscribe, this ties the life of the observer to the life of the object with the event. Without full knowledge of your program, that is all the farther up the chain I can go, but I think it should be sufficient for you to determine the lifetime of the observable.
This actually points out a potential "memory leak" that you can have with standard .NET events, objects keeping all their event subscribers alive, which leads to your second question. If you do not keep a reference to the IDisposable, you will never be able to unsubscribe from the event and your object will continue to receive notices, even after you close the view it is related to. If the event source does not live longer than the view, this may not be a problem, but I recommend using the disposable.
There is nothing "un-Rx" about this, and Rx even includes a nice class to use as an alternative to the List if you want, System.Reactive.Disposables.CompositeDisposable.
Gideon is incorrect here. The semantics of how Rx use IDisposable are different than typical .NET. The IDisposable returned from Subscribe is if you want to unsubscribe earlier than the end of the IObservable. If you don't want to do this, complicating your code with all of the extra disposable management is unnecessary.
Common practice is to implement IDisposable interface and dispose your disposable members here.

Eventhandlers and application lifetime objects in c# - should I unhook?

Say I've got an object that exists for the duration of an application. Let's call it GlobalWorker. GlobalWorker has events e.g. UserLoggedIn to which other objects can subscribe. Now imagine I've got a Silverlight page or an asp.net page or something, that subscribes to the UserLoggedIn event when it is constructed.
public SomePage()
{
GlobalWorker.Instance.UserLoggedIn += new EventHandler(OnUserLoggedIn);
}
private void OnLoggedIn(object sender, EventArgs e)
{
}
Does the existence of this event prevent the page from being garbage collected? If so, what's the best pattern to use in this instance: weak event-handlers, move the subscription to the Load event and unsubscribe in the UnLoad event?
Use Weak Events.
This is a common problem in WPF and it is good you have thought about it.
Yes the behavior prevents the page from being GC.
The reason being is that UserLoggedIn will hold a reference to SomePage indefinitely. There is no explicit removal of the handler and since weak events are not being used it will not implicitly get removed either.
You can use weak events as another poster stated, you can also re-think your design to some degree and see if you can functionalize or encapsulate the eventing behavior. Perhaps the data is all that needs to be global in this instance (user credentials), where as the event can be kept isolated.
You could also de-register in the handler itself if this was a one-off event you cared about. It really boils down to your specific need and instance, weak event pattern is the pattern to deal with this application wide but does not mean you have to use that pattern in each and every instance this problem surfaces.

Doing your own custom .NET event processing loop

A few years ago, I read a book that described how you could override the default event 'dispatcher' implementation in .NET with your own processor.
class foo {
public event EventHandler myEvent;
...
}
...
myFoo.myEvent += myBar1.EventHandler;
myFoo.myEvent += myBar2.EventHandler;
Whenever the event fires, both myBar1 and myBar2 handlers will be called.
As I recall, the default implementation of this loop uses a linked list and simply iterates over the list and calls the EventHandler delegates in order.
My question is two fold:
Does someone know which book I was reading?
Why would you want to override the default implementation (which might be answered in the book)?
Edit: The book I was referring to was indeed Jeffrey Richter's CLR via C#
It could have been one of many books or web articles.
There are various reasons why you might want to change how events are subscribed/unsubscribed:
If you have many events, many of which may well not be subscribed to, you may want to use EventHandlerList to lower your memory usage
You may wish to log subscription/unsubscription
You may wish to use a weak reference to avoid the subscriber's lifetime from being tied to yours
You may wish to change the locking associated with subscription/unsubscription
I'm sure there are more - those are off the top of my head :)
EDIT: Also note that there's a difference between having a custom way of handling subscription/unsubscription and having a custom way of raising the event (which may call GetInvocationList and guarantee that all handlers are called, regardless of exceptions, for example).
I seem to remember something similar in Jeffrey Richter's CLR via C#. Edit: I definitely do remember that he goes into detail about it.
There are a few different reasons for taking control of event registration. One of them is to reduce code bloat when you've got TONS of events. I think Jeffrey went into this in detail within the book...
No
You might, for example, need to break the call chain based on the result of one of the handlers. Say your CustomEventArgs object has a property 'Blocked', which when set to true suppresses all further event handler invocations.

Categories