Warum verursacht die Implementierung einer Schnittstelle in einer Unterklasse von EventSource zur Laufzeit eine Ausnahme?

7

Ich versuche, Event Tracing für Windows (ETW) zu verwenden in meiner .NET-Anwendung über die EventSource Klasse, die in enthalten war. NET 4.5. Ich untergliedere EventSource als MyEventSource und versuche, eine Schnittstelle IMyEventSource (zu Spottzwecken) wie folgt zu implementieren:

%Vor%

Wenn ich PerfView ausführe und diesen Code ausführe, erhalte ich IndexOutOfRangeException beim Aufruf von WriteEvent . Wenn ich die Schnittstelle entferne, indem ich den Code ändere ...

%Vor%

... dann funktioniert alles gut.

Hier ist der Code, den ich in beiden Fällen zum Testen verwendet habe:

%Vor%

Warum bricht meine Unterklasse von EventSource , wenn sie einfach eine Schnittstelle implementiert?

Hier ist ein verwandte Post .

    
Mike 30.04.2013, 13:48
quelle

5 Antworten

10

Als die Frage gestellt wurde, war die Antwort von @LarsSkovslund korrekt. Allerdings mit der stabilen Version von Microsoft.Diagnostics.Tracing.EventSource ( nicht das System .Diagnostics.Tracing.EventSource, das seit Version 4.5 in das .Net Framework eingebaut ist, Microsoft änderte dies entsprechend ihrem Blogpost :

  

Mit der RTM-Version haben wir einige der Validierung der Ereignisquellen gelockert   Regeln , um bestimmte erweiterte Nutzungsszenarien zu ermöglichen.

     

Die zwei Änderungen in diesem Bereich:

     
  • EventSource-Typen können jetzt Schnittstellen implementieren , um die Verwendung von Ereignisquellentypen in erweiterten Protokollsystemen zu ermöglichen, die Schnittstellen zu   Definieren Sie ein gemeinsames Protokollierungsziel.

  •   
  • Das Konzept eines Quellentyps für Hilfsereignisse (definiert als abstrakte Klasse, abgeleitet von EventSource) wird eingeführt, um den Freigabecode zu unterstützen   über mehrere Ereignisquellentypen in einem Projekt (z. B. für optimierte   WriteEvent () Überladungen).

  •   
    
magicandre1981 19.04.2014, 09:03
quelle
4

Wenn die EventSource-Klasse ihre Ereignisstruktur basierend auf der Reflektion aufbaut, berücksichtigt sie nur direkte Methoden, z. geerbte Mitglieder werden in Ihrem Fall nicht mit der Verwendung von IMyEventSource berücksichtigt.

Sie erhalten die IndexOutOfRangeException, weil WriteEvent den Ereignis-ID-Parameter verwendet, um einen Deskriptorblock mit einem Index zu suchen, der mit der Ereignis-ID übereinstimmt, wodurch die Ausnahme ausgelöst wird, wenn der Index nicht existiert.

Also kurz DONT verwendete Schnittstellen, um Ihre ETW-Ereignisse mit EventSource zu definieren.

Prost   Lars

    
Lars Skovslund 01.05.2013 07:15
quelle
4

Obwohl die Ereignisquelle keine Schnittstelle implementieren kann, ist es möglich, sie mit einer anderen Klasse zu umbrechen. (Dies ist eine Instanz des Adapterentwurfsmusters )

%Vor%     
Christopher Stevenson 16.05.2013 07:18
quelle
1

Ab heute (29. September 2014) funktioniert der Code des ursprünglichen Posters nicht mit dem systemeigenen Code, der mit .NET 4.5 ausgeliefert wird. Es erzeugt immer noch eine Ausnahme "IndexOutOfRange", und wie er sagt, tut es dies nur, wenn die ETW-Ereignisse überwacht werden (ich verwende PerfView).

Das heißt, ich habe mit .NET Version 4.0 mit der Microsoft EventSource-Bibliothek von nuget.org überprüft, und sein Code funktioniert damit.

Als nächstes habe ich Microsoft EventSource Library von nuget in einem .NET Version 4.5-Projekt installiert. Ich vergewisserte mich, dass ich von Microsoft.Diagnostics.Tracing.EventSource und nicht von System.Diagnostics.Tracing.EventSource von der nativen .NET 4.5-Bibliothek erbte. Das funktionierte, aber ich fand auch, dass ich jene Methoden markieren musste, die von der Schnittstelle mit dem Attribut [Microsoft.Diagnostics.Tracing.Event (int)] geerbt haben.

Ich habe auch einige seltsame Verhaltensweisen beobachtet, die ich nicht erklären konnte. Manchmal werden einige meiner Ereignisse in PerfView als "EventID (0)" anstelle des Methodennamens angezeigt. Manchmal habe ich unerwartete IndexOutOfRange-Ausnahmen bekommen. Soweit ich es beurteilen kann, blieb die Registrierung aus einem früheren Versuch in Erinnerung. Ich habe angefangen, meine EventSource-Klasse zwischen den Tests umzubenennen, und ich bekam diese Probleme nicht mehr.

JR

    
jrv 29.09.2014 19:25
quelle
0

Es gibt eine Problemumgehung für dieses Problem (leider weiß ich nicht, wie ich das Problem erklären soll). Wenn deine Methode mit NonEventAttribute dekoriert ist, kannst du deine Schnittstelle benutzen.

Ihre Schnittstelle:

%Vor%

Und die Implementierung:

%Vor%     
Thomas 15.12.2015 09:59
quelle