Przeglądaj źródła

Only stopwatch the time in a debug build

CPKreuz 1 rok temu
rodzic
commit
7f15b17c25

+ 23 - 22
src/PixiEditor/Helpers/DeadlockDetectionHelper.cs

@@ -67,12 +67,12 @@ public class DeadlockDetectionHelper
 
         if (Debugger.IsAttached)
         {
-            CheckDispatcher(Timeout.Infinite, DispatcherPriority.Send);
+            CheckDispatcher(Timeout.Infinite, null, DispatcherPriority.Send);
         }
         else
         {
             int timeout = mainThread.ThreadState.HasFlag(ThreadState.WaitSleepJoin) ? 8500 : 25000;
-            bool close = !CheckDispatcher(timeout, DispatcherPriority.Send);
+            bool close = !CheckDispatcher(timeout, null, DispatcherPriority.Send);
         
             if (close)
             {
@@ -188,55 +188,56 @@ public class DeadlockDetectionHelper
 
     private bool CheckNotBusy()
     {
-        var stopwatch = new Stopwatch();
+        DebugLogStopwatch stopwatch = null;
+        DebugLogStopwatch.Create(ref stopwatch);
         
-        stopwatch.Start();
-        bool isFree = CheckDispatcher(1000, DispatcherPriority.Background);
-        stopwatch.Stop();
+        // First deadlock check
+        bool isFree = CheckDispatcher(1000, stopwatch, DispatcherPriority.Background);
 
         if (isFree)
             return true;
         
-        Debug.WriteLine($"-------- First deadlock check time [0] {stopwatch.Elapsed}");
+        stopwatch.Log("-------- First deadlock check time [0] {0}");
         
+        // Second deadlock check
         for (var i = 0; i < 3; i++)
         {
-            stopwatch.Restart();
-            isFree = CheckDispatcher(400, DispatcherPriority.Input);
-            stopwatch.Stop();
+            isFree = CheckDispatcher(400, stopwatch, DispatcherPriority.Input);
 
             if (isFree)
                 return true;
             
-            Debug.WriteLine($"-------- Second deadlock check time [{i}] {stopwatch.Elapsed}");
+            stopwatch.Log($"-------- Second deadlock check time [{i}] {{0}}");
         }
         
-        isFree = CheckDispatcher(1600, DispatcherPriority.Input);
+        // Third deadlock check
+        isFree = CheckDispatcher(1600, stopwatch, DispatcherPriority.Input);
 
-        stopwatch.Restart();
-        Debug.WriteLine($"-------- Third deadlock check time [0] {stopwatch.Elapsed}");
-        stopwatch.Stop();
-        
         if (isFree)
             return true;
 
+        stopwatch.Log("-------- Third deadlock check time [0] {0}");
+        
+        // Forth deadlock
         int lastTimeout = mainThread.ThreadState.HasFlag(ThreadState.WaitSleepJoin) ? 1400 : 3500;
-        isFree = CheckDispatcher(lastTimeout, DispatcherPriority.Send);
+        isFree = CheckDispatcher(lastTimeout, stopwatch, DispatcherPriority.Send);
 
-        stopwatch.Restart();
-        Debug.WriteLine($"-------- Fourth deadlock check time [0] {stopwatch.Elapsed}");
-        stopwatch.Stop();
+        stopwatch.Log("-------- Fourth deadlock check time [0] {0}");
         
         return isFree;
     }
 
-    private bool CheckDispatcher(int timeout, DispatcherPriority priority)
+    private bool CheckDispatcher(int timeout, DebugLogStopwatch stopwatch, DispatcherPriority priority)
     {
+        stopwatch.Restart();
         var task = Task.Run(() => dispatcher.Invoke(ReturnTrue, TimeSpan.FromMilliseconds(timeout), priority) as bool? ?? false);
 
         var waitTimeout = (int)(timeout != -1 ? timeout * 1.2 : timeout);
         
-        return task.Wait(waitTimeout) && task.Result;
+        bool result = task.Wait(waitTimeout) && task.Result;
+        stopwatch.Stop();
+
+        return result;
     }
 
     private static bool ReturnTrue() => true;

+ 68 - 0
src/PixiEditor/Helpers/DebugLogStopwatch.cs

@@ -0,0 +1,68 @@
+using System.Diagnostics;
+
+namespace PixiEditor.Helpers;
+
+/// <summary>
+/// A DEBUG build only stopwatch than can log to <see cref="Debug"/>.Write()
+/// </summary>
+public class DebugLogStopwatch
+{
+    public Stopwatch Stopwatch { get; }
+    
+    private DebugLogStopwatch()
+    {
+        Stopwatch = new Stopwatch();
+    }
+
+    /// <summary>
+    /// Sets the reference to <param name="stopwatch"/> a new instance of <see cref="DebugLogStopwatch"/> only in a DEBUG build
+    /// </summary>
+    /// <param name="stopwatch"></param>
+    [Conditional("DEBUG")]
+    public static void Create(ref DebugLogStopwatch? stopwatch)
+    {
+        stopwatch = new DebugLogStopwatch();
+    }
+}
+
+internal static class DebugLogStopwatchExtensions
+{
+    /// <summary>
+    /// Starts the Stopwatch if not null
+    /// </summary>
+    [Conditional("DEBUG")]
+    public static void Start(this DebugLogStopwatch? stopwatch) => stopwatch?.Stopwatch.Start();
+
+    /// <summary>
+    /// Restarts the Stopwatch if not null
+    /// </summary>
+    [Conditional("DEBUG")]
+    public static void Restart(this DebugLogStopwatch? stopwatch) => stopwatch?.Stopwatch.Restart();
+    
+    /// <summary>
+    /// Stops the Stopwatch if not null
+    /// </summary>
+    [Conditional("DEBUG")]
+    public static void Stop(this DebugLogStopwatch? stopwatch) => stopwatch?.Stopwatch.Stop();
+
+    /// <summary>
+    /// Logs the time using the <param name="format"/> and stops the Stopwatch if not null
+    /// </summary>
+    [Conditional("DEBUG")]
+    public static void LogAndStop(this DebugLogStopwatch? stopwatch, string format)
+    {
+        if (stopwatch == null)
+        {
+            return;
+        }
+
+        stopwatch.Log(format);
+        stopwatch.Stopwatch.Stop();
+    }
+    
+    /// <summary>
+    /// Logs the time using the <param name="format"/> if the stopwatch is not null
+    /// </summary>
+    [Conditional("DEBUG")]
+    public static void Log(this DebugLogStopwatch? stopwatch, string format) => Debug.WriteLine(format, stopwatch?.Stopwatch.Elapsed);
+}