Skip to content

Commit

Permalink
Don't block on clearing the output window on the UI thread when gener…
Browse files Browse the repository at this point in the history
…ating a file (#60281)
  • Loading branch information
davidwengier committed Mar 20, 2022
1 parent 33764a8 commit 8aa4e0a
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Microsoft.CodeAnalysis.PdbSourceDocument
/// </summary>
internal interface IPdbSourceDocumentLogger
{
Task ClearAsync();
void Clear();
void Log(string message);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,8 @@ internal sealed class PdbSourceDocumentMetadataAsSourceFileProvider : IMetadataA
var assemblyName = symbol.ContainingAssembly.Identity.Name;
var assemblyVersion = symbol.ContainingAssembly.Identity.Version.ToString();

if (_logger is not null)
{
// We block to clear the log from the previous operation, so things don't get confusing
// if the log messages are delayed
await _logger.ClearAsync().ConfigureAwait(false);
}

// Clear the log so messages from the previously generated file don't confuse the user
_logger?.Clear();
_logger?.Log(FeaturesResources.Navigating_to_symbol_0_from_1, symbol, assemblyName);

var compilation = await project.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal sealed class PdbSourceDocumentOutputWindowLogger : IPdbSourceDocumentLo
private IVsOutputWindowPane? _outputPane;

private readonly IThreadingContext _threadingContext;
private readonly AsyncBatchingWorkQueue<string> _logItemsQueue;
private readonly AsyncBatchingWorkQueue<string?> _logItemsQueue;
private readonly IServiceProvider _serviceProvider;

private readonly CancellationTokenSource _cancellationTokenSource = new();
Expand All @@ -41,14 +41,14 @@ public PdbSourceDocumentOutputWindowLogger(SVsServiceProvider serviceProvider, I

var asyncListener = listenerProvider.GetListener(nameof(PdbSourceDocumentOutputWindowLogger));

_logItemsQueue = new AsyncBatchingWorkQueue<string>(
_logItemsQueue = new AsyncBatchingWorkQueue<string?>(
DelayTimeSpan.NearImmediate,
ProcessLogMessagesAsync,
asyncListener,
_cancellationTokenSource.Token);
}

private async ValueTask ProcessLogMessagesAsync(ImmutableArray<string> messages, CancellationToken cancellationToken)
private async ValueTask ProcessLogMessagesAsync(ImmutableArray<string?> messages, CancellationToken cancellationToken)
{
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

Expand All @@ -60,7 +60,11 @@ private async ValueTask ProcessLogMessagesAsync(ImmutableArray<string> messages,
return;
}

if (pane is IVsOutputWindowPaneNoPump noPumpPane)
if (message is null)
{
pane.Clear();
}
else if (pane is IVsOutputWindowPaneNoPump noPumpPane)
{
noPumpPane.OutputStringNoPump(message + Environment.NewLine);
}
Expand All @@ -71,11 +75,9 @@ private async ValueTask ProcessLogMessagesAsync(ImmutableArray<string> messages,
}
}

public async Task ClearAsync()
public void Clear()
{
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync();

GetPane()?.Clear();
_logItemsQueue.AddWork((string?)null);
}

public void Log(string value)
Expand Down

0 comments on commit 8aa4e0a

Please sign in to comment.