Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@jasonmalinowski
Copy link
Member

This PR cleans up the final offenders so our package initialization for the C# package and the shared RoslynPackage do not transition to the UI thread anywhere. There are still UI thread transitions in the OnAfterPackageLoad, where we register event handlers for commands and object browser interfaces. VB is also still marked as not supporting background load to a COM marshalling issue to work around some legacy code.

At this point this somewhat moots the PackageLoadTasks infrastructure, but a follow-up will be made to this PR to remove that since that'll require some coordination and testing further.

This removes the eager creation on the UI thread. To maintain
compatibility with F# that accesses this on the UI thread, we'll fetch
it on-demand in that case.
We had some code scheduling to the UI thread to wait for the UI context
to be complete, but that's no longer necessary. Since we also had
multiple derived types all setting this up, but all of them had the
pattern in one way or another, this also just unifies the pattern
to just one case.
This trick means we don't have to switch to the UI thread to call
LoadPackage, but can stay on the background thread the whole time.
@jasonmalinowski jasonmalinowski self-assigned this Dec 18, 2025
@jasonmalinowski jasonmalinowski requested a review from a team as a code owner December 18, 2025 21:33
Comment on lines 20 to +32
get
{
Assumes.Present(_componentModel_doNotAccessDirectly);
return _componentModel_doNotAccessDirectly;
if (field is null)
{
// We should have been initialized asynchronously, but somebody is asking earlier than we expected, so fetch it synchronously.
var componentModel = (IComponentModel?)GetService(typeof(SComponentModel));
Assumes.Present(componentModel);
field = componentModel;
return field;
}

return field;
}
Copy link
Member

Choose a reason for hiding this comment

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

can this just be:

get => field ??= (IComponentModel?)GetService(typeof(SComponentModel)) ?? throw etc;

Copy link
Member Author

Choose a reason for hiding this comment

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

If we weren't using Assumes.Present, yes....hmmm....

Copy link
Member

Choose a reason for hiding this comment

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

That's why I have the throw :-)

base.RegisterInitializeAsyncWork(packageInitializationTasks);

packageInitializationTasks.AddTask(isMainThreadTask: true, task: PackageInitializationMainThreadAsync);
packageInitializationTasks.AddTask(isMainThreadTask: false, task: PackageInitializationBackgroundThreadAsync);
Copy link
Member

Choose a reason for hiding this comment

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

nice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants