diff options
author | therzok <marius.ungureanu@xamarin.com> | 2019-07-07 02:43:54 +0300 |
---|---|---|
committer | therzok <marius.ungureanu@xamarin.com> | 2019-07-07 02:46:37 +0300 |
commit | 5982bf5367c0f1d13aac5696b9e6fa2ff44a2684 (patch) | |
tree | 89e9d5406cf95c2cfbd3248c54d801aca48b3057 /main/src/core/MonoDevelop.Core | |
parent | 8a44a7c488a9e40bc4c3d5440b83833cf86c9b7b (diff) |
Refactor TimeInvoke code to deduplicate and simplify logic
Diffstat (limited to 'main/src/core/MonoDevelop.Core')
-rw-r--r-- | main/src/core/MonoDevelop.Core/CoreExtensions.EventHandlers.cs | 82 |
1 files changed, 40 insertions, 42 deletions
diff --git a/main/src/core/MonoDevelop.Core/CoreExtensions.EventHandlers.cs b/main/src/core/MonoDevelop.Core/CoreExtensions.EventHandlers.cs index 9c7fbbd8e7..9c526ba604 100644 --- a/main/src/core/MonoDevelop.Core/CoreExtensions.EventHandlers.cs +++ b/main/src/core/MonoDevelop.Core/CoreExtensions.EventHandlers.cs @@ -68,31 +68,6 @@ namespace System } } - internal static void TimeInvoke<T> (this EventHandler<T> events, object sender, T args) - { - var sw = new Diagnostics.Stopwatch (); - foreach (var ev in events.GetInvocationList ()) { - try { - sw.Restart (); - ((EventHandler<T>)ev) (sender, args); - sw.Stop (); - - lock (timings) { - if (!timings.TryGetValue (sender, out var timingPair)) { - timings [sender] = timingPair = new Dictionary<Reflection.MethodInfo, TimeSpan> (); - } - - if (!timingPair.TryGetValue (ev.Method, out var previousTime)) - previousTime = TimeSpan.Zero; - - timingPair [ev.Method] = previousTime.Add (sw.Elapsed); - } - } catch (Exception ex) { - LoggingService.LogInternalError (ex); - } - } - } - static readonly Dictionary<object, Dictionary<MethodInfo, TimeSpan>> timings = new Dictionary<object, Dictionary<MethodInfo, TimeSpan>> (); internal static void TimingsReport () @@ -101,44 +76,67 @@ namespace System var source = kvp.Key; var values = kvp.Value; - Console.WriteLine ("Source {0}", source); + LoggingService.LogInfo ("Source {0}", source); foreach (var timeReport in values.OrderByDescending (x => x.Value)) { - Console.WriteLine ("{0} - {1} {2}", timeReport.Value.ToString (), timeReport.Key.DeclaringType, timeReport.Key); + LoggingService.LogInfo ("{0} - {1} {2}", timeReport.Value.ToString (), timeReport.Key.DeclaringType, timeReport.Key); + } + } + } + + static void RecordTime (object id, MethodInfo methodInfo, TimeSpan value) + { + lock (timings) { + if (!timings.TryGetValue (id, out var timingInfo)) { + timings [id] = timingInfo = new Dictionary<MethodInfo, TimeSpan> (MethodInfoEqualityComparer.Instance); } + + if (!timingInfo.TryGetValue (methodInfo, out var previousTime)) + previousTime = TimeSpan.Zero; + + timingInfo [methodInfo] = previousTime.Add (value); } } - internal static void TimeInvoke (this EventHandler events, object sender, EventArgs args) + static void TimeInvoke (Action<Delegate, object, EventArgs> call, Delegate[] del, object sender, EventArgs args, object groupId) { var sw = new Diagnostics.Stopwatch (); - foreach (var ev in events.GetInvocationList ()) { + foreach (var ev in del) { try { sw.Restart (); - ((EventHandler)ev) (sender, args); + call (ev, sender, args); sw.Stop (); - lock (timings) { - if (!timings.TryGetValue (sender, out var timingPair)) { - timings [sender] = timingPair = new Dictionary<MethodInfo, TimeSpan> (MethodInfoEqualityComparer.Instance); - } - - if (!timingPair.TryGetValue (ev.Method, out var previousTime)) - previousTime = TimeSpan.Zero; - - timingPair [ev.Method] = previousTime.Add (sw.Elapsed); - } + RecordTime (groupId ?? sender, ev.Method, sw.Elapsed); } catch (Exception ex) { LoggingService.LogInternalError (ex); } } } + internal static void TimeInvoke<T> (this EventHandler<T> events, object sender, T args, object groupId = null) where T:EventArgs + => TimeInvoke ( + (del, s, a) => ((EventHandler<T>)del).Invoke (s, (T)a), + events.GetInvocationList (), // This can be a perf issue, do we have a different way to query it? + sender, + args, + groupId + ); + + internal static void TimeInvoke (this EventHandler events, object sender, EventArgs args, object groupId = null) + => TimeInvoke ( + (del, s, a) => ((EventHandler)del).Invoke (s, a), + events.GetInvocationList (), // This can be a perf issue, do we have a different way to query it? + sender, + args, + groupId + ); + sealed class MethodInfoEqualityComparer : IEqualityComparer<MethodInfo> { public static MethodInfoEqualityComparer Instance = new MethodInfoEqualityComparer (); + public bool Equals (MethodInfo x, MethodInfo y) - => x.Name == y.Name - && x.DeclaringType == y.DeclaringType; + => x.Name == y.Name && x.DeclaringType == y.DeclaringType; public int GetHashCode (MethodInfo obj) => obj.Name.GetHashCode () ^ obj.DeclaringType.GetHashCode (); |