In the latest video by Rx team Bart De Smet: Rx Update - .NET 4.5, Async, WinRT I saw that WinRT events exposed to .NET by some really strange metadata, more preciesly - add_/remove_ pair methods signature:
EventRegistrationToken add_MyEvent(EventHandler<MyEventArgs> handler) { … }
void remove_MyEvent(EventRegistrationToken registrationToken) { … }
It looks really great, allowing unsubscribing from event by "disposing" the registration token (Rx does the same kind of thing, returning IDisposable instance from Subscribe() method). So it's became possible to easily unsubscribe lamba-expressions from events, but...
So how does C# allows for working with this kind of events? In .NET it's possible to subscribe an method (static and instance) with one instance on delegate and unsubscribe with completely another delegate instance pointed to the same method. So if I using an WinRT event and just do unsubscribing of some delegate type instance in C#... where did compiler get the correct EventRegistrationToken? How all this magic works?
-- update --
Actually EventRegistrationToken doesn't allows to unsubscribe simply by calling some kind of Dispose() method, that is really sadly:
public struct EventRegistrationToken
{
internal ulong Value { get; }
internal EventRegistrationToken(ulong value)
public static bool operator ==(EventRegistrationToken left, EventRegistrationToken right)
public static bool operator !=(EventRegistrationToken left, EventRegistrationToken right)
public override bool Equals(object obj)
public override int GetHashCode()
}
-- update2 --
WinRT interoperability actually uses global table of registration tokens when subscribing WinRT events with managed objets. For example, interop code for removing handlers looks like this:
internal static void RemoveEventHandler<T>(Action<EventRegistrationToken> removeMethod, T handler)
{
object target = removeMethod.Target;
var eventRegistrationTokenTable = WindowsRuntimeMarshal.ManagedEventRegistrationImpl.GetEventRegistrationTokenTable(target, removeMethod);
EventRegistrationToken obj2;
lock (eventRegistrationTokenTable)
{
List<EventRegistrationToken> list;
if (!eventRegistrationTokenTable.TryGetValue(handler, out list)) return;
if (list == null || list.Count == 0) return;
int index = list.Count - 1;
obj2 = list[index];
list.RemoveAt(index);
}
removeMethod(obj2);
}
That is really sadly.
When you add or remove a delegate to an WinRT event, like this:
this.Loaded += MainPage_Loaded;
this.Loaded -= MainPage_Loaded;
It looks just like you were working with normal .Net events. But this code actually compiles to something like this (Reflector seems to have some trouble decompiling WinRT code, but I think this is what the code actually does):
WindowsRuntimeMarshal.AddEventHandler<RoutedEventHandler>(
new Func<RoutedEventHandler, EventRegistrationToken>(this.add_Loaded),
new Action<EventRegistrationToken>(remove_Loaded),
new RoutedEventHandler(this.MainPage_Loaded));
WindowsRuntimeMarshal.RemoveEventHandler<RoutedEventHandler>(
new Action<EventRegistrationToken>(this.remove_Loaded),
new RoutedEventHandler(this.MainPage_Loaded));
This code won't actually compile, because you can't access the add_ and remove_ methods from C#. But you can that in IL, and that's exactly what the compiler does.
It looks like WindosRuntimeMarshal keeps all those EventRegistrationTokens and uses them to unsubscribe when necessary.
Would you accept "there are some amazingly clever people working on the C# language projection" as an answer?
More seriously, what you've discovered is the low level ABI (binary) implementation of the event pattern, the C# language projection knows this pattern and knows how to expose it as C# events. There are classes inside the CLR that implement this mapping.
Related
There are situations where I'm quite fond of static events, but the fact that I rarely see them in other people's code makes me wonder if I'm missing something important. I found a lot of discussions about static events on this site, but most of them deal with situations that I'm not interested in (like on static classes) or where I wouldn't think of using them in the first place.
What I am interested in are situations where I might have many instances of something and a single instance of a long-living "manager" object that reacts to something on those instances. A very simple example to illustrate what I mean:
public class God {
//the list of followers is really big and changes all the time,
//it seems like a waste of time to
//register/unregister events for each and every one...
readonly List<Believer> Believers = new List<Believer>();
God() {
//...so instead let's have a static event and listen to that
Believer.Prayed += this.Believer_Prayed;
}
void Believer_Prayed(Believer believer, string prayer) {
//whatever
}
}
public class Believer {
public static event Action<Believer, string> Prayed;
void Pray() {
if (Prayed != null) {
Prayed(this, "can i have stuff, please");
}
}
}
To me, this looks like a much cleaner and simpler solution than having an instance event and I don't have to monitor changes in the believers collection either. In cases where the Believer class can "see" the God-type class, I might sometimes use a NotifyGodOfPrayer()-method instead (which was the preferred answer in a few similar questions), but often the Believer-type class is in a "Models"-assembly where I can't or don't want to access the God class directly.
Are there any actual downsides to this approach?
Edit: Thanks to everyone who has already taken the time to answer.
My example may be bad, so I would like to clarify my question:
If I use this kind of static events in situations, where
I'm sure there will only ever be one instance of the subscriber-object
that is guaranteed to exist as long as the application is running
and the number of instances I'm watching is huge
then are there potential problems with this approach that I'm not aware of?
Unless the answer to that question is "yes", I'm not really looking for alternative implementations, though I really appreciate everyone trying to be helpful.
I'm not looking for the most pretty solution (I'd have to give that prize to my own version simply for being short and easy to read and maintain :)
One important thing to know about events is that they cause objects which are hooked to an event not to be garbage collected until event owner is garbage collected, or until event handler is unhooked.
To put it into your example, if you had a polytheistic pantheon with many gods, where you promoted and demoted gods such as
new God("Svarog");
new God("Svantevit");
new God("Perun");
gods would remain in your RAM while they are attached to Believer.Prayed. This would cause your application to leak gods.
I'll comment on design decision also, but I understand that example you made is maybe not best copy of your real scenario.
It seems more reasonable to me not to create dependency from God to Believer, and to use events. Good approach would be to create an event aggregator which would stand between believers and gods. For example:
public interface IPrayerAggregator
{
void Pray(Believer believer, string prayer);
void RegisterGod(God god);
}
// god does
prayerAggregator.RegisterGod(this);
// believer does
prayerAggregator.Pray(this, "For the victory!");
Upon Pray method being called, event aggregator calls appropriate method of God class in turn. To manage references and avoid memory leaks, you could create UnregisterGod method or hold gods in collection of weak references such as
public class Priest : IPrayerAggregator
{
private List<WeakReference> _gods;
public void Pray(Believer believer, string prayer)
{
foreach (WeakReference godRef in _gods) {
God god = godRef.Target as God;
if (god != null)
god.SomeonePrayed(believer, prayer);
else
_gods.Remove(godRef);
}
}
public void RegisterGod(God god)
{
_gods.Add(new WeakReference(god, false));
}
}
Quick tip: Temporarily store event delegate as listeners might unhook their event handlers
void Pray() {
var handler = Prayed;
if (handler != null) {
handler(this, "can i have stuff, please");
}
}
Edit
Having in mind details you added about your scenario (huge number of event invokers, constant and single event watcher) I think you chose right scenario, purely for efficiency reasons. It creates least memory and cpu overhead. I wouldn't take this approach generally, but for scenario you described static event is very pragmatic solution that I might take.
One downside I see is flow of control. If your event listener is created in single instance as you say, then I would leverage singleton (anti)pattern and invoke method of God from Believer directly.
God.Instance.Pray(this, "For the victory!");
//or
godInstance.Pray(this, "For the victory!");
Why? Because then you get more granular control over performing action of praying. If you decide down the line that you need to subclass Believer to a special kind that doesn't pray on certain days, then you would have control over this.
I actually think that having an instance even would be cleaner and defiantly more readable.
It is much more simple to view it as, an instance is preying, so his pray event gets trigger. And I don't see ant downsides for that. I don't think that monitor changes is not more of a hustle than monitoring the static event. but is the correct way to go...
Monitoring the list:
Change the list to be an ObservableCollection (and take a look at NotifyCollectionChangedEventArgs ).
Monitor it by:
public class God {
readonly ObservableCollection<Believer> Believers = new ObservableCollection<Believer>();
public God() {
Believers = new ObservableCollection<T>();
Believers.CollectionChanged += BelieversListChanged;
}
private void BelieversListChanged(object sender, NotifyCollectionChangedEventArgs args) {
if ((e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) && e.OldItems != null)
{
foreach (var oldItem in e.OldItems)
{
var bel= (Believer)e.oldItem;
bel.Prayed -= Believer_Prayed;
}
}
if((e.Action==NotifyCollectionChangedAction.Add || e.Action==NotifyCollectionChangedAction.Replace) && e.NewItems!=null)
{
foreach(var newItem in e.NewItems)
{
foreach (var oldItem in e.OldItems)
{
var bel= (Believer)e.newItem;
bel.Prayed += Believer_Prayed;
}
}
}
}
void Believer_Prayed(Believer believer, string prayer) {
//whatever
}
}
I decompiled an assembly using ILSpy, and one class in particular got my attention:
public class CustomTextStream : NetworkStream
{
private EventHandler<CustomEventArgs> someEvent;
public event EventHandler<CustomEventArgs> SomePublicEvent
{
add
{
EventHandler<CustomEventArgs> eventHandler = this.someEvent;
EventHandler<CustomEventArgs> eventHandler2;
do
{
eventHandler2 = eventHandler;
EventHandler<CustomEventArgs> value2 =
(EventHandler<CustomEventArgs>)Delegate.Combine(eventHandler2, value);
eventHandler =
Interlocked.CompareExchange<EventHandler<CustomEventArgs>>(
ref this.someEvent, value2, eventHandler2);
}
while (eventHandler != eventHandler2);
}
remove
{
// similar stuff...
}
}
}
Further in the code, seems like private delegate is used to fire an actual event:
if (something != null && somethingElse != 0)
{
this.someEvent(this, new CustomEventArgs(someArg));
}
The question: Can someone guess what could be the idea behind this custom accessors, assuming that some "compile/decompile magic" didn't take place? I'm not much familiar with IL, btw...
(Side note: the application is multi-threaded and utilizes networking, obviously.)
This is a new event handler code generated by compiler. It was introduced in C# 4 (C# 3 version was different)
Interlocked.CompareExchange compares first argument with third, and if they are equal, replaces first argument with second. This is a thread-safe operation. Loop is used for a case when after assigning a variable eventHandler2 and before check, another thread changes this delegate. In this case, Interlocked.CompareExchange does not perform exchange, loop condition does not evaluate to true and next attempt is made.
C# 3 generated simple code in event handlers:
add { lock(this) { changed = changed + value; } }
Which had lower performance and could introduce deadlocks.
There is a great series of articles on this subject:
Events get a little overhaul in C# 4
Events get a little overhaul in C# 4, Part II
Hypothetically speaking, if I had two methods (event handlers) driven by the same event, which method is executed first?
Example:
obj.SomeEvent += new SomeEventHandler(method1);
obj.SomeEvent += new SomeEventHandler(method2);
Which is called first?
Thanks!
It's up to the event publisher, but usually it would be whichever handler was added to the event first. That's the default implementation for an event which is basically implemented using a delegate. So for example:
SomeDelegate eventHandlers = null;
eventHandlers += FirstHandler;
eventHandlers += SecondHandler;
eventHandlers(...);
That will definitely call FirstHandler before SecondHandler. However, there's no guarantee that an event will be implemented just using delegates like that.
EDIT: While the event handling behaviour is up to the event publisher, the delegate combination part is well-specified in the C# language specification, section 7.8.4:
[...] Otherwise, the result of the operation is a new delegate instance that, when invoked, invokes the first operand and then invokes the second operand.
The BCL Delegate.Combine method makes a similar guarantee (emphasis mine):
(Return value) A new delegate with an invocation list that concatenates the invocation lists of a and b in that order. Returns a if b is null, returns b if a is a null reference, and returns a null reference if both a and b are null references.
The first subscribed one. "First in - first served".
The default implementation will cause event handlers to be called in the order they were added, however, it is possible to customize this behaviour. If the behaviour is customized, the client cannot tell this. So the real answer to your question is that the order in which event handlers is raised "depends" and could even change at runtime, however, the vast majority of events have default implementation.
For example:
public class ReverseBling
{
private readonly List<EventHandler> _blings = new List<EventHandler>();
public event EventHandler Bling
{
add
{
_blings.Add(value);
}
remove
{
_blings.Remove(value);
}
}
public void RaiseBling()
{
for (int i = _blings.Count - 1; i >= 0; i--)
{
_blings[i](this, EventArgs.Empty);
}
}
}
private static void Main()
{
ReverseBling bling = new ReverseBling();
bling.Bling += delegate { Console.WriteLine(0);};
bling.Bling += delegate { Console.WriteLine(1); };
bling.Bling += delegate { Console.WriteLine(2); };
bling.RaiseBling();
}
Output:
2
1
0
There is no way of telling which event handler will be invoked first. Many people think the first one to subscribe will be invoked first (which is normally the case) but not specified by the CLI.
I have an IObservable<byte[]> that I transform into an IObservable<XDocument> using some intermediate steps:
var observedXDocuments =
from b in observedBytes
// Lot of intermediate steps to transform byte arrays into XDocuments
select xDoc;
At some point in time, I'm interested in the observed XDocuments so I subscribe an IObserver<XDocument>. At a later point in time, I would like to subscribe another IObserver<XDocument> and dispose of the old one.
How can I do this in one atomic operation, without loosing any observed XDocument? I could do something like:
oldObserver.Dispose();
observedXDocuments.Subscribe(newObserver);
I'm worried though, that between these two calls, I could loose an XDocument. If I switch the two calls, it could happen that I receive the same XDocument twice.
I'd probably add a layer of indirection. Write a class called ExchangeableObserver, subscribe it to your observable, and keep it permanently subscribed. The job of ExchangeableObserver is to delegate everything to a given sub-observer. But the programmer is allowed to change the sub-observer being delegated to at any time. In my example I have an Exchange() method. Something like:
public class ExchangeableObserver<T> : IObserver<T> {
private IObserver<T> inner;
public ExchangeableObserver(IObserver<T> inner) {
this.inner=inner;
}
public IObserver<T> Exchange(IObserver<T> newInner) {
return Interlocked.Exchange(ref inner, newInner);
}
public void OnNext(T value) {
inner.OnNext(value);
}
public void OnCompleted() {
inner.OnCompleted();
}
public void OnError(Exception error) {
inner.OnError(error);
}
}
you can use a semaphore that makes shure that while IObservable<byte[]> prepares for IObservable<XDocument> no observer-change takes place.
pseudocode how this could be done (not testet)
System.Threading.ReaderWriterLockSlim criticalSection
= new System.Threading.ReaderWriterLockSlim(...);
... converting from `IObservable<byte[]>` to `IObservable<XDocument>`
criticalSection.EnterReadLock();
Call IObservable<XDocument>
criticalSection.ExitReadLock();
.... replacing IObservable<XDocument>
criticalSection.EnterWriteLock();
Call change IObservable<XDocument>
criticalSection.ExitWriteLock();
Edit: with Call IObservable<XDocument>
> What exactly do you mean with the line `Call IObservable<XDocument>`?
I interprete your sentense
> I have an `IObservable<byte[]>` that I transform
> into an `IObservable<XDocument>` using some intermediate steps...
that you have registered an eventhandler for IObservable<byte[]> that creates a XDocument from byte[] and then calls
something that triggers an event for IObservable<XDocument>.
Call IObservable<XDocument> means the code that triggers the followup-event
Is there any best practice with respect to coding style with respect to explicit use of the delegate keyword instead of using a lambda?
e.g.
new Thread(() =>
{
// work item 1
// work item 2
}).Start();
new Thread(delegate()
{
// work item 1
// work item 2
}).Start();
I think the lambda looks better. If the lambda is better style, what's the point of having a delegate keyword, other than for the fact that it existed before lambdas were implemented?
Lambda syntax is much more generalised, and the designers have said that they'd ideally remove the old overlapping syntaxes (dont have a citation, but it's probably Eric Lippert or Jon Skeet in a book or a podcast).
But delegate allows you to ignore parameters, e.g.:
object.Event += delegate { };
versus having to say:
object.Event += (sender,args) => { };
which can be very useful in large argument lists and/or to make the code more resilient to refactoring.
EDIT: As pointed out by Yann Schwartz in another answer (now unfortunately deleted), a very neat usage of this trick is in order to provide a default hander for an event using the Null Object pattern:-
class MyClassThatFiresWithoutTheTrick
{
public event EventHandler MyEvent; // implicit = null
// Need a method to keep this DRY as each fire requires a null check - see Framework Design Guidelines by Abrams and Cwalina
protected virtual void OnMyEvent()
{
// need to take a copy to avoid race conditions with _removes
// See CLR via C# 3rd edition p 264-5 for reason why this happens to work
//var handler = MyEvent;
// BUT THIS is the preferred version
var handler = Interlocked.CompareExchange( ref MyEvent, null, null);
// Need to do this check as it might not have been overridden
if( handler == null)
return;
handler( this, EventArgs.Empty );
}
}
class MyClassThatFiresWithTheTrick
{
public event EventHandler MyEvent = delegate{};
protected virtual void OnMyEvent()
{
MyEvent( this, EventArgs.Empty );
}
}
(though what you might often end up doing is an Inline Method of OnMyEvent, making the code even shorter again.)