зеркало из https://github.com/dotnet/razor.git
Don't get IVsAsyncFileChangeEx on background thread
`VisualStudioFileChangeTrackerFactory` retrieves an `IVsAsyncFileChangeEx` service in its constructor. Because this is an `[ImportingConstructor]` it will likely be called on the thread pool and implicitly marshal to the UI thread to perform a QI as part of retrieving the service. This can cause a hang if the UI thread is tied up with other work, such as when a solution is loaded. This change avoids retrieving `IVsAsyncFileChangeEx` until its needed. This does block on retrieving the service. However, avoiding that will require a more substantial change that I'll follow up with on `main`.
This commit is contained in:
Родитель
18e4175ac5
Коммит
9e109f88a7
|
@ -13,10 +13,10 @@ namespace Microsoft.VisualStudio.Editor.Razor.Documents;
|
|||
[Export(typeof(IFileChangeTrackerFactory))]
|
||||
internal class VisualStudioFileChangeTrackerFactory : IFileChangeTrackerFactory
|
||||
{
|
||||
private readonly IErrorReporter _errorReporter;
|
||||
private readonly IVsAsyncFileChangeEx _fileChangeService;
|
||||
private readonly ProjectSnapshotManagerDispatcher _projectSnapshotManagerDispatcher;
|
||||
private readonly ProjectSnapshotManagerDispatcher _dispatcher;
|
||||
private readonly JoinableTaskContext _joinableTaskContext;
|
||||
private readonly IErrorReporter _errorReporter;
|
||||
private readonly JoinableTask<IVsAsyncFileChangeEx> _getFileChangeServiceTask;
|
||||
|
||||
[ImportingConstructor]
|
||||
public VisualStudioFileChangeTrackerFactory(
|
||||
|
@ -25,10 +25,17 @@ internal class VisualStudioFileChangeTrackerFactory : IFileChangeTrackerFactory
|
|||
ProjectSnapshotManagerDispatcher dispatcher,
|
||||
IErrorReporter errorReporter)
|
||||
{
|
||||
_errorReporter = errorReporter;
|
||||
_fileChangeService = (IVsAsyncFileChangeEx)serviceProvider.GetService(typeof(SVsFileChangeEx));
|
||||
_projectSnapshotManagerDispatcher = dispatcher;
|
||||
_dispatcher = dispatcher;
|
||||
_joinableTaskContext = joinableTaskContext;
|
||||
_errorReporter = errorReporter;
|
||||
|
||||
var jtf = _joinableTaskContext.Factory;
|
||||
_getFileChangeServiceTask = jtf.RunAsync(async () =>
|
||||
{
|
||||
await jtf.SwitchToMainThreadAsync();
|
||||
|
||||
return (IVsAsyncFileChangeEx)serviceProvider.GetService(typeof(SVsFileChangeEx));
|
||||
});
|
||||
}
|
||||
|
||||
public IFileChangeTracker Create(string filePath)
|
||||
|
@ -38,6 +45,9 @@ internal class VisualStudioFileChangeTrackerFactory : IFileChangeTrackerFactory
|
|||
throw new ArgumentException(SR.ArgumentCannotBeNullOrEmpty, nameof(filePath));
|
||||
}
|
||||
|
||||
return new VisualStudioFileChangeTracker(filePath, _errorReporter, _fileChangeService, _projectSnapshotManagerDispatcher, _joinableTaskContext);
|
||||
// TODO: Make IFileChangeTrackerFactory.Create(...) asynchronous to avoid blocking here.
|
||||
var fileChangeService = _getFileChangeServiceTask.Join();
|
||||
|
||||
return new VisualStudioFileChangeTracker(filePath, _errorReporter, fileChangeService, _dispatcher, _joinableTaskContext);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче