summaryrefslogtreecommitdiff
path: root/src/System.Private.CoreLib
diff options
context:
space:
mode:
authorStephen Toub <stoub@microsoft.com>2019-07-16 15:28:53 -0400
committerGitHub <noreply@github.com>2019-07-16 15:28:53 -0400
commit7f713f7067ffb6adaa1549f626f6bd04128f0de6 (patch)
tree684bbccabe853958f6f06b62324e62863995dd23 /src/System.Private.CoreLib
parent7f1dd83ddb159e2469b85145f228fa60ab3682e2 (diff)
downloadcoreclr-7f713f7067ffb6adaa1549f626f6bd04128f0de6.tar.gz
coreclr-7f713f7067ffb6adaa1549f626f6bd04128f0de6.tar.bz2
coreclr-7f713f7067ffb6adaa1549f626f6bd04128f0de6.zip
Disable debugger evaluation of ValueTask<T>.Result (#25727)
If the debugger evaluates a `ValueTask<T>`'s `Result`, that counts as the "you should only consume a `ValueTask<T>`" once, and ends up breaking / hanging / throwing exceptions and other bad stuff while stepping through code in the debugger. This commit addresses that in two ways: 1. Adds `[DebuggerBrowsable(Never)]` to `Result` to prevent it from showing up in debugger views. 2. Adds a NotifyOfCrossThreadDependency call to its ToString. This prevents the debugger from using ToString to show an implicit representation of the instance, and it forces the developer explicitly trying to access ToString (e.g. in the watch window) to click a button acknowleding the impact. (Post 3.0, we should consider removing the `ValueTask<T>.ToString()` override altogether.)
Diffstat (limited to 'src/System.Private.CoreLib')
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs3
1 files changed, 3 insertions, 0 deletions
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
index 7ffb4bb8ec..285d3bf308 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/ValueTask.cs
@@ -740,6 +740,7 @@ namespace System.Threading.Tasks
}
/// <summary>Gets the result.</summary>
+ [DebuggerBrowsable(DebuggerBrowsableState.Never)] // prevent debugger evaluation from invalidating an underling IValueTaskSource<T>
public TResult Result
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -780,6 +781,8 @@ namespace System.Threading.Tasks
{
if (IsCompletedSuccessfully)
{
+ Debugger.NotifyOfCrossThreadDependency(); // prevent debugger evaluation from invalidating an underling IValueTaskSource<T> unless forced
+
TResult result = Result;
if (result != null)
{