-
Notifications
You must be signed in to change notification settings - Fork 4.1k
Another small set of package initialization optimizations #77646
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
Changes from 2 commits
566a1c7
581ab0e
670e2b6
f03bd7c
70f4569
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -58,32 +58,32 @@ private async Task PackageInitializationMainThreadAsync(IProgress<ServiceProgres | |
RegisterEditorFactory(editorFactory); | ||
} | ||
|
||
RegisterLanguageService(typeof(TLanguageService), async cancellationToken => | ||
{ | ||
// Ensure we're on the BG when creating the language service. | ||
await TaskScheduler.Default; | ||
|
||
// Create the language service, tell it to set itself up, then store it in a field | ||
// so we can notify it that it's time to clean up. | ||
_languageService = CreateLanguageService(); | ||
await _languageService.SetupAsync(cancellationToken).ConfigureAwait(false); | ||
|
||
return _languageService.ComAggregate!; | ||
}); | ||
|
||
var miscellaneousFilesWorkspace = this.ComponentModel.GetService<MiscellaneousFilesWorkspace>(); | ||
|
||
// awaiting an IVsTask guarantees to return on the captured context | ||
await shell.LoadPackageAsync(Guids.RoslynPackageId); | ||
|
||
RegisterMiscellaneousFilesWorkspaceInformation(miscellaneousFilesWorkspace); | ||
packageRegistrationTasks.AddTask( | ||
isMainThreadTask: false, | ||
task: (IProgress<ServiceProgressData> progress, PackageRegistrationTasks packageRegistrationTasks, CancellationToken cancellationToken) => | ||
{ | ||
RegisterLanguageService(typeof(TLanguageService), async cancellationToken => | ||
{ | ||
// Ensure we're on the BG when creating the language service. | ||
await TaskScheduler.Default; | ||
Comment on lines
+72
to
+73
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We already said isMainThreadTask: false, why saying this a second time? I'd frankly can't explain why that RegisterLanguageServer function exists in the first place, if that was the concern. It has this comment:
But there's nothing special it's doing with it... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's the callback when the service is created, I don't know if we can guarantee what context we are on when that happens. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right of course. That'd be something we should follow up with -- hopefully we have some way to say we can be created on a background thread -- it'd be silly for the service system to bounce to the UI thread if we didn't need it. |
||
|
||
if (!_shell.IsInCommandLineMode()) | ||
{ | ||
// not every derived package support object browser and for those languages | ||
// this is a no op | ||
RegisterObjectBrowserLibraryManager(); | ||
} | ||
// Create the language service, tell it to set itself up, then store it in a field | ||
// so we can notify it that it's time to clean up. | ||
_languageService = CreateLanguageService(); | ||
await _languageService.SetupAsync(cancellationToken).ConfigureAwait(false); | ||
|
||
return _languageService.ComAggregate!; | ||
}); | ||
|
||
RegisterMiscellaneousFilesWorkspaceInformation(miscellaneousFilesWorkspace); | ||
|
||
return Task.CompletedTask; | ||
}); | ||
} | ||
|
||
protected override async Task OnAfterPackageLoadedAsync(CancellationToken cancellationToken) | ||
|
@@ -92,6 +92,13 @@ protected override async Task OnAfterPackageLoadedAsync(CancellationToken cancel | |
|
||
await JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); | ||
|
||
if (_shell != null && !_shell.IsInCommandLineMode()) | ||
{ | ||
// not every derived package support object browser and for those languages | ||
// this is a no op | ||
RegisterObjectBrowserLibraryManager(); | ||
} | ||
|
||
LoadComponentsInUIContextOnceSolutionFullyLoadedAsync(cancellationToken).Forget(); | ||
} | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Moving this to the background should be safe -- this is not written to have UI thread assumptions in the constructors. See the comments in OpenTextBufferProvider's constructor specifically for ensuring that's safe. This wasn't the case a few years back but this was generally modernized.
If you're wanting to keep the changes small to manage risk better, do this in a follow up PR (but don't forget about it.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally tried that and it threw. Let me see if I can find out where that dependency is.