Wie WinRT-Ereignisse mit .NET zusammenarbeiten

8

Im neuesten Video vom Rx-Team Bart De Smet: Rx-Aktualisierung - .NET 4.5, Async, WinRT Ich habe gesehen, dass WinRT-Ereignisse mit .NET durch einige wirklich seltsame Metadaten, genauer gesagt, konfrontiert wurden - add_ / remove_ Signatur der Paarmethoden:

%Vor%

Es sieht wirklich toll aus, indem man das Registrierungstoken "entsorgt" (Rx macht das Gleiche und gibt IDisposable instance von Subscribe() method zurück). So wurde es möglich, Lambda-Ausdrücke von Ereignissen einfach abzumelden, aber ...

Wie ermöglicht C # die Arbeit mit dieser Art von Ereignissen? In .NET ist es möglich, eine Methode (static und instance) mit einer Instanz auf Delegate zu subskribieren und mit einer anderen Delegierteninstanz, die auf dieselbe Methode verweist, abzumelden. Wenn ich also ein WinRT-Ereignis verwende und nur einige Delegattyp-Instanzen in C # abbestellt ... wo hat der Compiler die richtige EventRegistrationToken bekommen? Wie funktioniert all diese Magie?

- Aktualisierung -

Tatsächlich erlaubt EventRegistrationToken nicht, sich einfach durch Aufruf einer Art von Dispose() -Methode abzumelden, das ist wirklich traurig:

%Vor%

- update2 -

Die WinRT-Interoperabilität verwendet tatsächlich die globale Tabelle der Registrierungstoken beim Abonnieren von WinRT-Ereignissen mit verwalteten Objekten. Zum Beispiel sieht der Interop-Code zum Entfernen von Handlern folgendermaßen aus:

%Vor%

Das ist wirklich traurig.

    
ControlFlow 14.10.2011, 23:21
quelle

2 Antworten

14

Wenn Sie einen Delegaten zu einem WinRT-Ereignis hinzufügen oder entfernen, etwa so:

%Vor%

Es sieht so aus, als ob Sie mit normalen .Net-Ereignissen arbeiten. Aber dieser Code kompiliert tatsächlich zu so etwas (Reflector scheint Probleme beim Dekompilieren von WinRT-Code zu haben, aber ich denke, das ist, was der Code tatsächlich tut):

%Vor%

Dieser Code wird nicht wirklich kompiliert, weil Sie nicht auf die Methoden add_ und remove_ von C # zugreifen können. Aber Sie können das in IL, und das ist genau das, was der Compiler macht.

Es sieht aus wie WindosRuntimeMarshal behält all diese EventRegistrationToken s und verwendet sie, um sich bei Bedarf abzumelden.

    
svick 14.10.2011, 23:52
quelle
9

Würden Sie akzeptieren, dass "einige unglaublich clevere Leute an der C # -Projektion arbeiten"?

Genauer gesagt, was Sie entdeckt haben, ist die Implementierung des Ereignismusters auf niedriger Ebene (binär), die C # -Projektion kennt dieses Muster und weiß, wie es als C # -Ereignisse verfügbar gemacht wird. Innerhalb der CLR gibt es Klassen, die diese Zuordnung implementieren.

    
Larry Osterman 15.10.2011 06:16
quelle