From 2d086e46efe184b531f798d85541c441fa23fee5 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 5 Jun 2020 14:50:35 -0500 Subject: [PATCH 1/2] Remove WinRT specific code from EventSource. Follow up to #36715 --- .../Diagnostics/Tracing/ActivityTracker.cs | 4 +- .../Diagnostics/Tracing/EventDescriptor.cs | 16 +- .../Diagnostics/Tracing/EventProvider.cs | 2 +- .../System/Diagnostics/Tracing/EventSource.cs | 164 +----------------- .../Diagnostics/Tracing/StubEnvironment.cs | 8 +- .../Tracing/TraceLogging/PropertyValue.cs | 22 +-- .../Tracing/TraceLogging/Statics.cs | 14 +- .../TraceLogging/TraceLoggingEventSource.cs | 6 +- 8 files changed, 28 insertions(+), 208 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs index 07c2112878f9c7..9f46e13c38305f 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/ActivityTracker.cs @@ -228,7 +228,7 @@ public void Enable() } catch (NotImplementedException) { -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) // send message to debugger without delay System.Diagnostics.Debugger.Log(0, null, "Activity Enabled() called but AsyncLocals Not Supported (pre V4.6). Ignoring Enable"); #endif @@ -381,7 +381,7 @@ private unsafe void CreateActivityPathGuid(out Guid idRet, out int activityPathG { // TODO FIXME - differentiate between AD inside PCL int appDomainID = 0; -#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN) +#if (!ES_BUILD_STANDALONE) appDomainID = System.Threading.Thread.GetDomainID(); #endif // We start with the appdomain number to make this unique among appdomains. diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs index 02ba4d715ea4c9..5bdc4c3ee68750 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventDescriptor.cs @@ -18,21 +18,7 @@ namespace System.Diagnostics.Tracing #if ES_BUILD_STANDALONE [System.Security.Permissions.HostProtection(MayLeakOnAbort = true)] #endif - - /* - EventDescriptor was public in the separate System.Diagnostics.Tracing assembly(pre NS2.0), - now the move to CoreLib marked them as private. - While they are technically private (it's a contract used between the library and the ILC toolchain), - we need them to be rooted and exported from shared library for the system to work. - For now I'm simply marking them as public again.A cleaner solution might be to use.rd.xml to - root them and modify shared library definition to force export them. - */ -#if ES_BUILD_PN - public -#else - internal -#endif - struct EventDescriptor + internal struct EventDescriptor { #region private [FieldOffset(0)] diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs index dbc70abfb741db..850c12eac99d27 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventProvider.cs @@ -610,7 +610,7 @@ private unsafe bool GetDataFromController(int etwSessionId, dataStart = 0; if (filterData == null) { -#if (!ES_BUILD_PCL && !ES_BUILD_PN && TARGET_WINDOWS) +#if (!ES_BUILD_PCL && TARGET_WINDOWS) string regKey = @"\Microsoft\Windows\CurrentVersion\Winevt\Publishers\{" + m_providerId + "}"; if (IntPtr.Size == 8) regKey = @"Software\Wow6432Node" + regKey; diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index a62a188c618541..130d8abbe457e6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -1469,7 +1469,7 @@ private unsafe void Initialize(Guid eventSourceGuid, string eventSourceName, str m_etwProvider = etwProvider; #if TARGET_WINDOWS -#if (!ES_BUILD_STANDALONE && !ES_BUILD_PN) +#if (!ES_BUILD_STANDALONE) // API available on OS >= Win 8 and patched Win 7. // Disable only for FrameworkEventSource to avoid recursion inside exception handling. if (this.Name != "System.Diagnostics.Eventing.FrameworkEventSource" || Environment.IsWindows8OrAbove) @@ -1831,11 +1831,8 @@ private static Guid GenerateGuidFromName(string name) if (dataType.IsEnum()) { dataType = Enum.GetUnderlyingType(dataType); -#if ES_BUILD_PN - int dataTypeSize = (int)dataType.TypeHandle.ToEETypePtr().ValueTypeSize; -#else + int dataTypeSize = System.Runtime.InteropServices.Marshal.SizeOf(dataType); -#endif if (dataTypeSize < sizeof(int)) dataType = typeof(int); goto Again; @@ -2452,49 +2449,8 @@ protected override void OnControllerCommand(ControllerCommand command, IDictiona /// code:m_eventData for where we use this. /// - /* - EventMetadata was public in the separate System.Diagnostics.Tracing assembly(pre NS2.0), - now the move to CoreLib marked them as private. - While they are technically private (it's a contract used between the library and the ILC toolchain), - we need them to be rooted and exported from shared library for the system to work. - For now I'm simply marking them as public again.A cleaner solution might be to use.rd.xml to - root them and modify shared library definition to force export them. - */ -#if ES_BUILD_PN - public -#else - internal -#endif - partial struct EventMetadata - { -#if ES_BUILD_PN - public EventMetadata(EventDescriptor descriptor, - EventTags tags, - bool enabledForAnyListener, - bool enabledForETW, - string name, - string message, - EventParameterType[] parameterTypes) - { - this.Descriptor = descriptor; - this.Tags = tags; - this.EnabledForAnyListener = enabledForAnyListener; - this.EnabledForETW = enabledForETW; -#if FEATURE_PERFTRACING - this.EnabledForEventPipe = false; -#endif - this.TriggersActivityTracking = 0; - this.Name = name; - this.Message = message; - this.Parameters = null!; - this.TraceLoggingEventTypes = null; - this.ActivityOptions = EventActivityOptions.None; - this.ParameterTypes = parameterTypes; - this.HasRelatedActivityID = false; - this.EventHandle = IntPtr.Zero; - } -#endif - + internal partial struct EventMetadata + { public EventDescriptor Descriptor; public IntPtr EventHandle; // EventPipeEvent handle. public EventTags Tags; @@ -2514,13 +2470,8 @@ public EventMetadata(EventDescriptor descriptor, public TraceLoggingEventTypes? TraceLoggingEventTypes; public EventActivityOptions ActivityOptions; - -#if ES_BUILD_PN - public EventParameterType[] ParameterTypes; -#endif } -#if !ES_BUILD_PN private static int GetParameterCount(EventMetadata eventData) { return eventData.Parameters.Length; @@ -2532,101 +2483,6 @@ private static Type GetDataType(EventMetadata eventData, int parameterId) } private const bool m_EventSourcePreventRecursion = false; -#else - private static int GetParameterCount(EventMetadata eventData) - { - int paramCount; - if (eventData.Parameters == null) - { - paramCount = eventData.ParameterTypes.Length; - } - else - { - paramCount = eventData.Parameters.Length; - } - - return paramCount; - } - - private static Type GetDataType(EventMetadata eventData, int parameterId) - { - Type dataType; - if (eventData.Parameters == null) - { - dataType = EventTypeToType(eventData.ParameterTypes[parameterId]); - } - else - { - dataType = eventData.Parameters[parameterId].ParameterType; - } - - return dataType; - } - - private static readonly bool m_EventSourcePreventRecursion = true; - - public enum EventParameterType - { - Boolean, - Byte, - SByte, - Char, - Int16, - UInt16, - Int32, - UInt32, - Int64, - UInt64, - IntPtr, - Single, - Double, - Decimal, - Guid, - String - } - - private static Type EventTypeToType(EventParameterType type) - { - switch (type) - { - case EventParameterType.Boolean: - return typeof(bool); - case EventParameterType.Byte: - return typeof(byte); - case EventParameterType.SByte: - return typeof(sbyte); - case EventParameterType.Char: - return typeof(char); - case EventParameterType.Int16: - return typeof(short); - case EventParameterType.UInt16: - return typeof(ushort); - case EventParameterType.Int32: - return typeof(int); - case EventParameterType.UInt32: - return typeof(uint); - case EventParameterType.Int64: - return typeof(long); - case EventParameterType.UInt64: - return typeof(ulong); - case EventParameterType.IntPtr: - return typeof(IntPtr); - case EventParameterType.Single: - return typeof(float); - case EventParameterType.Double: - return typeof(double); - case EventParameterType.Decimal: - return typeof(decimal); - case EventParameterType.Guid: - return typeof(Guid); - case EventParameterType.String: - return typeof(string); - default: - // TODO: should I throw an exception here? - return null!; - } - } -#endif // This is the internal entry point that code:EventListeners call when wanting to send a command to a // eventSource. The logic is as follows @@ -3058,11 +2914,9 @@ internal static Attribute GetCustomAttributeHelper(Type type, Type attributeType // When that is the case, we have the build the custom assemblies on a member by hand. internal static Attribute? GetCustomAttributeHelper(MemberInfo member, Type attributeType, EventManifestOptions flags = EventManifestOptions.None) { -#if !ES_BUILD_PN - // On ProjectN, ReflectionOnly() always equals false. AllowEventSourceOverride is an option that allows either Microsoft.Diagnostics.Tracing or + // AllowEventSourceOverride is an option that allows either Microsoft.Diagnostics.Tracing or // System.Diagnostics.Tracing EventSource to be considered valid. This should not mattter anywhere but in Microsoft.Diagnostics.Tracing (nuget package). if (!member.Module.Assembly.ReflectionOnly() && (flags & EventManifestOptions.AllowEventSourceOverride) == 0) -#endif // !ES_BUILD_PN { // Let the runtime to the work for us, since we can execute code in this context. Attribute? firstAttribute = null; @@ -3074,7 +2928,7 @@ internal static Attribute GetCustomAttributeHelper(Type type, Type attributeType return firstAttribute; } -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) foreach (CustomAttributeData data in CustomAttributeData.GetCustomAttributes(member)) { if (AttributeTypeNamesMatch(attributeType, data.Constructor.ReflectedType!)) @@ -3116,7 +2970,7 @@ internal static Attribute GetCustomAttributeHelper(Type type, Type attributeType } return null; -#else // ES_BUILD_PCL && ES_BUILD_PN +#else // ES_BUILD_PCL // Don't use nameof here because the resource doesn't exist on some platforms, which results in a compilation error. throw new ArgumentException("EventSource_PCLPlatformNotSupportedReflection", "EventSource"); #endif @@ -3705,7 +3559,7 @@ private static void DebugCheckEvent(ref Dictionary? eventsByName /// The literal value or -1 if the value could not be determined. private static int GetHelperCallFirstArg(MethodInfo method) { -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) // Currently searches for the following pattern // // ... // CAN ONLY BE THE INSTRUCTIONS BELOW @@ -3834,7 +3688,7 @@ internal void ReportOutOfBandMessage(string msg) { try { -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) // send message to debugger without delay System.Diagnostics.Debugger.Log(0, null, string.Format("EventSource Error: {0}{1}", msg, Environment.NewLine)); #endif diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs index 05a9f0eaa69e48..4e9415aa02e42d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/StubEnvironment.cs @@ -3,7 +3,7 @@ // See the LICENSE file in the project root for more information. using System; -#if ES_BUILD_PCL || ES_BUILD_PN +#if ES_BUILD_PCL using System.Collections.Generic; #endif using System.Reflection; @@ -209,7 +209,7 @@ public enum TypeCode { #endif internal static class ReflectionExtensions { -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) // // Type extension methods @@ -239,11 +239,7 @@ internal static class ReflectionExtensions public static Assembly Assembly(this Type type) { return type.GetTypeInfo().Assembly; } public static IEnumerable GetProperties(this Type type) { -#if ES_BUILD_PN - return type.GetProperties(); -#else return type.GetRuntimeProperties(); -#endif } public static MethodInfo? GetGetMethod(this PropertyInfo propInfo) { return propInfo.GetMethod; } public static Type[] GetGenericArguments(this Type type) { return type.GenericTypeArguments; } diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs index 645aab27244e4a..5db76aa09bcaa7 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/PropertyValue.cs @@ -21,13 +21,7 @@ namespace System.Diagnostics.Tracing /// /// To get the value of a property quickly, use a delegate produced by . /// -#if ES_BUILD_PN - [CLSCompliant(false)] - public -#else - internal -#endif - readonly unsafe struct PropertyValue + internal readonly unsafe struct PropertyValue { /// /// Union of well-known value types, to avoid boxing those types. @@ -208,12 +202,7 @@ private static Func GetReferenceTypePropertyGetter return helper.GetPropertyGetter(property); } -#if ES_BUILD_PN - public -#else - private -#endif - abstract class TypeHelper + private abstract class TypeHelper { public abstract Func GetPropertyGetter(PropertyInfo property); @@ -223,12 +212,7 @@ protected Delegate GetGetMethod(PropertyInfo property, Type propertyType) } } -#if ES_BUILD_PN - public -#else - private -#endif - sealed class ReferenceTypeHelper : TypeHelper where TContainer : class? + private sealed class ReferenceTypeHelper : TypeHelper where TContainer : class? { public override Func GetPropertyGetter(PropertyInfo property) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs index 6d4dd919981b34..b7fa9d367aee23 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/Statics.cs @@ -360,7 +360,7 @@ public static IEnumerable GetProperties(Type type) public static MethodInfo? GetDeclaredStaticMethod(Type declaringType, string name) { MethodInfo? result; -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) result = declaringType.GetTypeInfo().GetDeclaredMethod(name); #else result = declaringType.GetMethod( @@ -375,7 +375,7 @@ public static bool HasCustomAttribute( Type attributeType) { bool result; -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) result = propInfo.IsDefined(attributeType); #else object[] attributes = propInfo.GetCustomAttributes( @@ -390,7 +390,7 @@ public static bool HasCustomAttribute( where AttributeType : Attribute { AttributeType? result = null; -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) foreach (var attrib in propInfo.GetCustomAttributes(false)) { result = attrib; @@ -410,7 +410,7 @@ public static bool HasCustomAttribute( where AttributeType : Attribute { AttributeType? result = null; -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) foreach (var attrib in type.GetTypeInfo().GetCustomAttributes(false)) { result = attrib; @@ -441,7 +441,7 @@ public static Type[] GetGenericArguments(Type type) } else { -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) IEnumerable ifaceTypes = type.GetTypeInfo().ImplementedInterfaces; #else Type[] ifaceTypes = type.FindInterfaces(IsGenericMatch, typeof(IEnumerable<>)); @@ -449,7 +449,7 @@ public static Type[] GetGenericArguments(Type type) foreach (Type ifaceType in ifaceTypes) { -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) if (!IsGenericMatch(ifaceType, typeof(IEnumerable<>))) { continue; @@ -478,7 +478,7 @@ public static bool IsGenericMatch(Type type, object? openType) public static Delegate CreateDelegate(Type delegateType, MethodInfo methodInfo) { Delegate result; -#if (ES_BUILD_PCL || ES_BUILD_PN) +#if (ES_BUILD_PCL) result = methodInfo.CreateDelegate( delegateType); #else diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs index aa13daa55b4d1d..168e529daa84e8 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/TraceLogging/TraceLoggingEventSource.cs @@ -441,7 +441,7 @@ private unsafe void WriteMultiMergeInner( descriptors[1].SetMetadata(pMetadata1, nameInfo.nameMetadata.Length, 1); descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif try @@ -625,7 +625,7 @@ private unsafe void WriteImpl( descriptors[2].SetMetadata(pMetadata2, eventTypes.typeMetadata.Length, 1); #endif // FEATURE_MANAGED_ETW -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) System.Runtime.CompilerServices.RuntimeHelpers.PrepareConstrainedRegions(); #endif EventOpcode opcode = (EventOpcode)descriptor.Opcode; @@ -732,7 +732,7 @@ private unsafe void WriteToAllListeners(string? eventName, ref EventDescriptor e DispatchToAllListeners(-1, eventCallbackArgs); } -#if (!ES_BUILD_PCL && !ES_BUILD_PN) +#if (!ES_BUILD_PCL) [System.Runtime.ConstrainedExecution.ReliabilityContract( System.Runtime.ConstrainedExecution.Consistency.WillNotCorruptState, System.Runtime.ConstrainedExecution.Cer.Success)] From f696861804b3fcc4d5e51c4a9b8a578edd465339 Mon Sep 17 00:00:00 2001 From: Eric Erhardt Date: Fri, 5 Jun 2020 16:49:16 -0500 Subject: [PATCH 2/2] Remove EventSource.GetMetadata method, which was only used by ProjectN. --- .../System/Diagnostics/Tracing/EventSource.cs | 56 +++---------------- 1 file changed, 7 insertions(+), 49 deletions(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs index 130d8abbe457e6..63d0b386bff26d 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Tracing/EventSource.cs @@ -649,15 +649,9 @@ protected EventSource(EventSourceSettings settings, params string[]? traits) { m_config = ValidateSettings(settings); - - GetMetadata(out Guid eventSourceGuid, out string? eventSourceName, out _, out _); - - if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null) - { - Type myType = this.GetType(); - eventSourceGuid = GetGuid(myType); - eventSourceName = GetName(myType); - } + Type myType = this.GetType(); + Guid eventSourceGuid = GetGuid(myType); + string eventSourceName = GetName(myType); Initialize(eventSourceGuid, eventSourceName, traits); } @@ -709,25 +703,6 @@ private unsafe void DefineEventPipeEvents() } #endif - internal virtual void GetMetadata(out Guid eventSourceGuid, out string? eventSourceName, out EventMetadata[]? eventData, out byte[]? manifestBytes) - { - // - // In ProjectN subclasses need to override this method, and return the data from their EventSourceAttribute and EventAttribute annotations. - // On other architectures it is a no-op. - // - // eventDescriptors needs to contain one EventDescriptor for each event; the event's ID should be the same as its index in this array. - // manifestBytes is a UTF-8 encoding of the ETW manifest for the type. - // - // This will be implemented by an IL rewriter, so we can't make this method abstract or the initial build of the subclass would fail. - // - eventSourceGuid = Guid.Empty; - eventSourceName = null; - eventData = null; - manifestBytes = null; - - return; - } - /// /// This method is called when the eventSource is updated by the controller. /// @@ -2771,28 +2746,11 @@ private void EnsureDescriptorsInitialized() #endif if (m_eventData == null) { - Guid eventSourceGuid = Guid.Empty; - - // Try the GetMetadata provided by the ILTransform in ProjectN. The default sets all to null, and in that case we fall back - // to the reflection approach. - GetMetadata(out eventSourceGuid, out string? eventSourceName, out EventMetadata[]? eventData, out byte[]? manifest); - - if (eventSourceGuid.Equals(Guid.Empty) || eventSourceName == null || eventData == null || manifest == null) - { - // GetMetadata failed, so we have to set it via reflection. - Debug.Assert(m_rawManifest == null); + // get the metadata via reflection. + Debug.Assert(m_rawManifest == null); + m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this); + Debug.Assert(m_eventData != null); - m_rawManifest = CreateManifestAndDescriptors(this.GetType(), Name, this); - Debug.Assert(m_eventData != null); - } - else - { - // GetMetadata worked, so set the fields as appropriate. - m_name = eventSourceName; - m_guid = eventSourceGuid; - m_eventData = eventData; - m_rawManifest = manifest; - } // TODO Enforce singleton pattern Debug.Assert(EventListener.s_EventSources != null, "should be called within lock on EventListener.EventListenersLock which ensures s_EventSources to be initialized"); foreach (WeakReference eventSourceRef in EventListener.s_EventSources)