提交 6752867c 编写于 作者: C CyrusNajmabadi

Acquire the user's selection up-front if we're on the UI thread for light-bulbs.

There are circumstances where the editor will call into us on hte UI thread and will then
block for results.  Right now this can deadlock as we may have kicked off work to the BG
that then awaits getting the selection back from the UI thread.  To avoid that, if we're on
the UI thread when we start, just go and get the selection and pass it along.
上级 d9254bc1
......@@ -604,6 +604,25 @@ public async Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet req
using (var asyncToken = provider.OperationListener.BeginAsyncOperation("HasSuggestedActionsAsync"))
{
// Acquire the user's selection up front, before we do any async work, so that we can
// directly grab it when we're on the UI thread. That way we don't have any reentrancy
// blocking concerns if VS wants to block on this call (for example, if the user
// explicitly invokes the 'show smart tag' command).
TextSpan? selection = null;
if (IsForeground())
{
// This operation needs to happen on UI thread because it needs to access textView.Selection.
selection = TryGetCodeRefactoringSelection(buffer, view, range);
}
else
{
await InvokeBelowInputPriority(() =>
{
// This operation needs to happen on UI thread because it needs to access textView.Selection.
selection = TryGetCodeRefactoringSelection(buffer, view, range);
}).ConfigureAwait(false);
}
var document = await GetMatchingDocumentAsync(range.Snapshot, cancellationToken).ConfigureAwait(false);
if (document == null)
{
......@@ -614,7 +633,7 @@ public async Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet req
return
await HasFixesAsync(provider, document, range, cancellationToken).ConfigureAwait(false) ||
await HasRefactoringsAsync(provider, document, buffer, view, range, cancellationToken).ConfigureAwait(false);
await HasRefactoringsAsync(provider, document, selection, cancellationToken).ConfigureAwait(false);
}
}
......@@ -655,11 +674,16 @@ public async Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet req
private async Task<bool> HasRefactoringsAsync(
SuggestedActionsSourceProvider provider,
Document document,
ITextBuffer buffer,
ITextView view,
SnapshotSpan range,
TextSpan? selection,
CancellationToken cancellationToken)
{
if (!selection.HasValue)
{
// this is here to fail test and see why it is failed.
Trace.WriteLine("given range is not current");
return false;
}
var workspace = document.Project.Solution.Workspace;
var supportsFeatureService = workspace.Services.GetService<IDocumentSupportsFeatureService>();
......@@ -667,28 +691,6 @@ public async Task<bool> HasSuggestedActionsAsync(ISuggestedActionCategorySet req
provider._codeRefactoringService != null &&
supportsFeatureService.SupportsRefactorings(document))
{
TextSpan? selection = null;
if (IsForeground())
{
// This operation needs to happen on UI thread because it needs to access textView.Selection.
selection = TryGetCodeRefactoringSelection(buffer, view, range);
}
else
{
await InvokeBelowInputPriority(() =>
{
// This operation needs to happen on UI thread because it needs to access textView.Selection.
selection = TryGetCodeRefactoringSelection(buffer, view, range);
}).ConfigureAwait(false);
}
if (!selection.HasValue)
{
// this is here to fail test and see why it is failed.
Trace.WriteLine("given range is not current");
return false;
}
return await Task.Run(
() => provider._codeRefactoringService.HasRefactoringsAsync(
document, selection.Value, cancellationToken),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册