diff --git a/src/Microsoft.VisualStudio.Threading/IPendingExecutionRequestState.cs b/src/Microsoft.VisualStudio.Threading/IPendingExecutionRequestState.cs new file mode 100644 index 000000000..9d73c4e8c --- /dev/null +++ b/src/Microsoft.VisualStudio.Threading/IPendingExecutionRequestState.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; + +namespace Microsoft.VisualStudio.Threading +{ + /// + /// An optional interface implemented by pending request state posted to the underline synchronization context. It allows synchronization context to remove completed requests. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + [Experimental("VSOnly")] + public interface IPendingExecutionRequestState + { + /// + /// Gets a value indicating whether the current request has been completed, and can be skipped. + /// + bool IsCompleted { get; } + } +} diff --git a/src/Microsoft.VisualStudio.Threading/JoinableTaskFactory.cs b/src/Microsoft.VisualStudio.Threading/JoinableTaskFactory.cs index 018f4c4bc..8395363b9 100644 --- a/src/Microsoft.VisualStudio.Threading/JoinableTaskFactory.cs +++ b/src/Microsoft.VisualStudio.Threading/JoinableTaskFactory.cs @@ -1058,7 +1058,9 @@ public void Dispose() /// A delegate wrapper that ensures the delegate is only invoked at most once. /// [DebuggerDisplay("{DelegateLabel}")] - internal class SingleExecuteProtector +#pragma warning disable VSOnly // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + internal class SingleExecuteProtector : IPendingExecutionRequestState +#pragma warning restore VSOnly // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. { /// /// Executes the delegate if it has not already executed. @@ -1112,6 +1114,11 @@ private SingleExecuteProtector(JoinableTask job) this.job = job; } + /// + /// Gets a value indicating whether the current request has been completed, and can be skipped. + /// + bool IPendingExecutionRequestState.IsCompleted => this.HasBeenExecuted; + /// /// Gets a value indicating whether this instance has already executed. /// diff --git a/src/Microsoft.VisualStudio.Threading/net472/PublicAPI.Unshipped.txt b/src/Microsoft.VisualStudio.Threading/net472/PublicAPI.Unshipped.txt index 0e00ec898..82ffde8aa 100644 --- a/src/Microsoft.VisualStudio.Threading/net472/PublicAPI.Unshipped.txt +++ b/src/Microsoft.VisualStudio.Threading/net472/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ Microsoft.VisualStudio.Threading.AsyncBarrier.SignalAndWait(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState.IsCompleted.get -> bool static Microsoft.VisualStudio.Threading.JoinableTaskContext.CreateNoOpContext() -> Microsoft.VisualStudio.Threading.JoinableTaskContext! \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.Threading/net8.0-windows/PublicAPI.Unshipped.txt b/src/Microsoft.VisualStudio.Threading/net8.0-windows/PublicAPI.Unshipped.txt index 0e00ec898..82ffde8aa 100644 --- a/src/Microsoft.VisualStudio.Threading/net8.0-windows/PublicAPI.Unshipped.txt +++ b/src/Microsoft.VisualStudio.Threading/net8.0-windows/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ Microsoft.VisualStudio.Threading.AsyncBarrier.SignalAndWait(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState.IsCompleted.get -> bool static Microsoft.VisualStudio.Threading.JoinableTaskContext.CreateNoOpContext() -> Microsoft.VisualStudio.Threading.JoinableTaskContext! \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.Threading/net8.0/PublicAPI.Unshipped.txt b/src/Microsoft.VisualStudio.Threading/net8.0/PublicAPI.Unshipped.txt index 0e00ec898..82ffde8aa 100644 --- a/src/Microsoft.VisualStudio.Threading/net8.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.VisualStudio.Threading/net8.0/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ Microsoft.VisualStudio.Threading.AsyncBarrier.SignalAndWait(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState.IsCompleted.get -> bool static Microsoft.VisualStudio.Threading.JoinableTaskContext.CreateNoOpContext() -> Microsoft.VisualStudio.Threading.JoinableTaskContext! \ No newline at end of file diff --git a/src/Microsoft.VisualStudio.Threading/netstandard2.0/PublicAPI.Unshipped.txt b/src/Microsoft.VisualStudio.Threading/netstandard2.0/PublicAPI.Unshipped.txt index 0e00ec898..82ffde8aa 100644 --- a/src/Microsoft.VisualStudio.Threading/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/Microsoft.VisualStudio.Threading/netstandard2.0/PublicAPI.Unshipped.txt @@ -1,2 +1,4 @@ Microsoft.VisualStudio.Threading.AsyncBarrier.SignalAndWait(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState +Microsoft.VisualStudio.Threading.IPendingExecutionRequestState.IsCompleted.get -> bool static Microsoft.VisualStudio.Threading.JoinableTaskContext.CreateNoOpContext() -> Microsoft.VisualStudio.Threading.JoinableTaskContext! \ No newline at end of file