Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delete task extension used only by the interactive window. #76450

Merged
merged 14 commits into from
Dec 17, 2024
Merged
51 changes: 25 additions & 26 deletions src/EditorFeatures/Core.Wpf/Interactive/ResetInteractive.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,35 @@ internal ResetInteractive(EditorOptionsService editorOptionsService, Func<string
_createImport = createImport;
}

internal Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
internal async Task ExecuteAsync(IInteractiveWindow interactiveWindow, string title)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

caller of this was going an await anyways, so there was no reason i could figure out for this to be written as task returning, with task continuations, instead of just normal async/await.

{
if (GetProjectProperties(out var references, out var referenceSearchPaths, out var sourceSearchPaths, out var projectNamespaces, out var projectDirectory, out var platform))
{
// Now, we're going to do a bunch of async operations. So create a wait
// indicator so the user knows something is happening, and also so they cancel.
var uiThreadOperationExecutor = GetUIThreadOperationExecutor();
var context = uiThreadOperationExecutor.BeginExecute(title, EditorFeaturesWpfResources.Building_Project, allowCancellation: true, showProgress: false);

var resetInteractiveTask = ResetInteractiveAsync(
interactiveWindow,
references,
referenceSearchPaths,
sourceSearchPaths,
projectNamespaces,
projectDirectory,
platform,
context);

// Once we're done resetting, dismiss the wait indicator and focus the REPL window.
return resetInteractiveTask.SafeContinueWith(
_ =>
{
context.Dispose();
ExecutionCompleted?.Invoke(this, new EventArgs());
},
TaskScheduler.FromCurrentSynchronizationContext());
try
{
// Now, we're going to do a bunch of async operations. So create a wait
// indicator so the user knows something is happening, and also so they cancel.
var uiThreadOperationExecutor = GetUIThreadOperationExecutor();
using var context = uiThreadOperationExecutor.BeginExecute(title, EditorFeaturesWpfResources.Building_Project, allowCancellation: true, showProgress: false);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a normal using now, so we don't need an explicit dispose.


// We want to come back onto the calling context to dismiss the wait indicator and to notify about
// execution completion.
await ResetInteractiveAsync(
interactiveWindow,
references,
referenceSearchPaths,
sourceSearchPaths,
projectNamespaces,
projectDirectory,
platform,
context).ConfigureAwait(true);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

intentionally CA(True) since hte original code did a ContinueWith with FromCurrentSynchronizationContext.

}
finally
{
// Once we're done resetting focus the REPL window.
ExecutionCompleted?.Invoke(this, new EventArgs());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in a finally, so we always do this regardless of cancellation (Teh semantics of SafeContinueWith).

}
}

return Task.CompletedTask;
}

private async Task ResetInteractiveAsync(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using Microsoft.CodeAnalysis.Shared.TestHooks;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Threading;
using Roslyn.Utilities;

namespace Microsoft.CodeAnalysis.Editor.Implementation.RenameTracking;
Expand Down Expand Up @@ -69,10 +70,8 @@ public TrackingSession(
// tagging.

OriginalName = snapshotSpan.GetText();
_isRenamableIdentifierTask = Task.Factory.SafeStartNewFromAsync(
() => DetermineIfRenamableIdentifierAsync(snapshotSpan, initialCheck: true),
_cancellationToken,
TaskScheduler.Default);
_isRenamableIdentifierTask = DetermineIfRenamableIdentifierAsync(snapshotSpan, initialCheck: true);
_isRenamableIdentifierTask.ReportNonFatalErrorAsync();

var asyncToken = _asyncListener.BeginAsyncOperation(GetType().Name + ".UpdateTrackingSessionAfterIsRenamableIdentifierTask");

Expand Down Expand Up @@ -157,7 +156,9 @@ public void Cancel()

private async Task<TriggerIdentifierKind> DetermineIfRenamableIdentifierAsync(SnapshotSpan snapshotSpan, bool initialCheck)
{
_threadingContext.ThrowIfNotOnBackgroundThread();
// Ensure we do this work on the background.
await TaskScheduler.Default;

var document = snapshotSpan.Snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document != null)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ internal abstract class UnitTestingIdleProcessor(
protected void Start()
{
Contract.ThrowIfFalse(_processorTask == null);
_processorTask = Task.Factory.SafeStartNewFromAsync(ProcessAsync, CancellationToken, TaskScheduler.Default);
_processorTask = ProcessAsync();
_processorTask.ReportNonFatalErrorAsync();
}

protected void UpdateLastAccessTime()
Expand Down Expand Up @@ -117,6 +118,9 @@ protected async Task<bool> WaitForIdleAsync(IExpeditableDelaySource expeditableD

private async Task ProcessAsync()
{
// Ensure we do this processing on the background.
await Task.Yield().ConfigureAwait(false);

while (!CancellationToken.IsCancellationRequested)
{
try
Expand Down
18 changes: 15 additions & 3 deletions src/VisualStudio/Core/Def/Implementation/GCManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,14 +85,26 @@ internal static void UseLowLatencyModeForProcessingUserInput()
{
GCSettings.LatencyMode = GCLatencyMode.SustainedLowLatency;

// Restore the LatencyMode a short duration after the
// last request to UseLowLatencyModeForProcessingUserInput.
// Restore the LatencyMode a short duration after the last UseLowLatencyModeForProcessingUserInput.
currentDelay = new ResettableDelay(s_delayMilliseconds, AsynchronousOperationListenerProvider.NullListener);
currentDelay.Task.SafeContinueWith(_ => RestoreGCLatencyMode(currentMode), TaskScheduler.Default);
RestoreGCLatencyModeWhenCompleteAsync(currentDelay.Task, currentMode).ReportNonFatalErrorAsync();
s_delay = currentDelay;
}

currentDelay?.Reset();
return;

async Task RestoreGCLatencyModeWhenCompleteAsync(Task task, GCLatencyMode latencyMode)
{
try
{
await task.ConfigureAwait(false);
}
finally
{
RestoreGCLatencyMode(latencyMode);
}
}
}

private static void RestoreGCLatencyMode(GCLatencyMode originalMode)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,12 @@ public static Task CompletesTrackingOperation(this Task task, IDisposable token)

return CompletesTrackingOperationSlow(task, token);

static Task CompletesTrackingOperationSlow(Task task, IDisposable token)
static async Task CompletesTrackingOperationSlow(Task task, IDisposable token)
{
return task.SafeContinueWith(
t => token.Dispose(),
CancellationToken.None,
TaskContinuationOptions.ExecuteSynchronously,
TaskScheduler.Default);
using (token)
{
await task.NoThrowAwaitableInternal(captureContext: false);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Utilities\StringEscapeEncoder.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\SyntaxPath.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\TaskExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\TaskFactoryExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\TopologicalSorter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Utilities\EventHandlerFactory.cs" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,6 @@ static TResult outerFunction(Task t, object? state)
return task.ContinueWith(outerFunction, continuationFunction, cancellationToken, continuationOptions | TaskContinuationOptions.LazyCancellation, scheduler);
}

[SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "This is a Task wrapper, not an asynchronous method.")]
public static Task SafeContinueWith(
this Task task,
Action<Task> continuationAction,
TaskScheduler scheduler)
{
return task.SafeContinueWith(continuationAction, CancellationToken.None, TaskContinuationOptions.None, scheduler);
}

public static Task<TResult> SafeContinueWithFromAsync<TInput, TResult>(
this Task<TInput> task,
Func<Task<TInput>, Task<TResult>> continuationFunction,
Expand Down

This file was deleted.

Loading