From 431fdf441b2e8096d1e825e21719032fd53fb14e Mon Sep 17 00:00:00 2001 From: I_SER_I Date: Wed, 23 Feb 2022 03:58:52 +0300 Subject: [PATCH 1/4] feat: add DebuggerDisplay method and attribute --- .../System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs index 675e83fe050909..ffaaefad1ffcea 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs @@ -7,6 +7,7 @@ namespace System.Diagnostics // hardware supports it. Otherwise, the class will fall back to DateTime // and uses ticks as a measurement. + [DebuggerDisplay("{DebuggerDisplay,nq}")] public partial class Stopwatch { private const long TicksPerMillisecond = 10000; @@ -150,5 +151,7 @@ private long GetElapsedDateTimeTicks() // convert high resolution perf counter to DateTime ticks return unchecked((long)(GetRawElapsedTicks() * s_tickFrequency)); } + + private string DebuggerDisplay => $"{this.Elapsed} (IsRunning = {_isRunning})"; } } From ec6a6ddcbcac9feaa88aee86036c3e259798d009 Mon Sep 17 00:00:00 2001 From: I_SER_I Date: Wed, 23 Feb 2022 12:11:40 +0300 Subject: [PATCH 2/4] refactor: remove 'this' --- .../System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs index ffaaefad1ffcea..d6212cd0bcf78b 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Diagnostics/Stopwatch.cs @@ -152,6 +152,6 @@ private long GetElapsedDateTimeTicks() return unchecked((long)(GetRawElapsedTicks() * s_tickFrequency)); } - private string DebuggerDisplay => $"{this.Elapsed} (IsRunning = {_isRunning})"; + private string DebuggerDisplay => $"{Elapsed} (IsRunning = {_isRunning})"; } } From 37e26d37f590a3a9cd79b6917aa127c22d0e8a83 Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Mon, 6 Jun 2022 23:41:34 +0000 Subject: [PATCH 3/4] Test --- .../tests/System/Diagnostics/Stopwatch.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs b/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs index 02226d4abe9ef2..f6ee4d0ff3d3fb 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs @@ -95,6 +95,19 @@ public static void StartNewAndRestart() } } + [Fact] + public static void DebuggerDisplay() + { + Stopwatch watch = new Stopwatch(); + Assert.Equal("{00:00:00} (IsRunning = false)", watch.DebuggerDisplay); + watch.Start(); + Thread.Sleep(10); + Assert.Contains("} (IsRunning = true)", watch.DebuggerDisplay); + watch.Stop(); + Assert.Contains("} (IsRunning = false)", watch.DebuggerDisplay); + Assert.NotContains("{00:00:00}", watch.DebuggerDisplay); + } + [OuterLoop("Sleeps for relatively long periods of time")] [Fact] public static void ElapsedMilliseconds_WithinExpectedWindow() From 3be4ec348b9a642bcce750e5e074677430f84c9e Mon Sep 17 00:00:00 2001 From: Dan Moseley Date: Tue, 7 Jun 2022 02:04:01 +0000 Subject: [PATCH 4/4] Fix test --- .../System.Runtime.Extensions.Tests.csproj | 1 + .../tests/System/Diagnostics/Stopwatch.cs | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj b/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj index 1e78f1533949d6..3e3e293778105c 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj +++ b/src/libraries/System.Runtime.Extensions/tests/System.Runtime.Extensions.Tests.csproj @@ -82,6 +82,7 @@ + diff --git a/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs b/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs index f6ee4d0ff3d3fb..273358d1a9f1dc 100644 --- a/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs +++ b/src/libraries/System.Runtime.Extensions/tests/System/Diagnostics/Stopwatch.cs @@ -2,6 +2,7 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.Collections.Generic; +using System.Reflection; using System.Threading; using Xunit; @@ -96,16 +97,24 @@ public static void StartNewAndRestart() } [Fact] - public static void DebuggerDisplay() + public static void DebuggerAttributesValid() { + DebuggerAttributes.ValidateDebuggerDisplayReferences(new Stopwatch()); + Stopwatch watch = new Stopwatch(); - Assert.Equal("{00:00:00} (IsRunning = false)", watch.DebuggerDisplay); + Assert.Equal("00:00:00 (IsRunning = False)", GetDebuggerDisplayProperty(watch)); watch.Start(); Thread.Sleep(10); - Assert.Contains("} (IsRunning = true)", watch.DebuggerDisplay); + Assert.Contains("(IsRunning = True)", GetDebuggerDisplayProperty(watch)); + Assert.DoesNotContain("00:00:00 ", GetDebuggerDisplayProperty(watch)); watch.Stop(); - Assert.Contains("} (IsRunning = false)", watch.DebuggerDisplay); - Assert.NotContains("{00:00:00}", watch.DebuggerDisplay); + Assert.Contains("(IsRunning = False)", GetDebuggerDisplayProperty(watch)); + Assert.DoesNotContain("00:00:00 ", GetDebuggerDisplayProperty(watch)); + + static string GetDebuggerDisplayProperty(Stopwatch value) + { + return (string)typeof(Stopwatch).GetProperty("DebuggerDisplay", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(value); + } } [OuterLoop("Sleeps for relatively long periods of time")]