Skip to content

Switch color loading to be async.#60205

Merged
CyrusNajmabadi merged 5 commits intodotnet:mainfrom
CyrusNajmabadi:asyncColorScheme
Mar 17, 2022
Merged

Switch color loading to be async.#60205
CyrusNajmabadi merged 5 commits intodotnet:mainfrom
CyrusNajmabadi:asyncColorScheme

Conversation

@CyrusNajmabadi
Copy link
Copy Markdown
Contributor

@CyrusNajmabadi CyrusNajmabadi requested a review from a team as a code owner March 16, 2022 20:46
@ghost ghost added the Area-IDE label Mar 16, 2022
if (_isInitialized)
return;

_ = _colorSchemeRegistryItems.GetValueAsync(CancellationToken.None);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Do we have a good sense what this fire-and-forget was doing before? As best I can tell the initialize path was going to block on this if/when we needed to change the theme right away in the call to UpdateColorScheme, and this isn't making things worse...but then what was this for?

Comment on lines +90 to +91
await _threadingContext.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So we have this code here:

// SLocalRegistry service is free-threaded -- see https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1408594.
// Note: not using IAsyncServiceProvider.GetServiceAsync<TService, TInterface> since the extension method might switch to UI thread.
// See https://devdiv.visualstudio.com/DevDiv/_workitems/edit/1408619/.
var localRegistry = (ILocalRegistry4?)await provider.GetServiceAsync(typeof(SLocalRegistry)).ConfigureAwait(false);
Contract.ThrowIfNull(localRegistry);
Contract.ThrowIfFalse(ErrorHandler.Succeeded(localRegistry.GetLocalRegistryRootEx((uint)__VsLocalRegistryType.RegType_UserSettings, out var rootHandle, out var rootPath)));

Which implies we can get to local registry values without needing a UI thread switch. I'm not sure if VSRegistry.RegistryRoot() is just doing exactly what we do there or whether we can refactor that and reuse it?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(this isn't wrong though, so better to keep the switch to UI thread if there is any uncertainty)

Comment on lines +154 to +155
await GetThemeIdAsync(_threadingContext.DisposalToken).ConfigureAwait(false),
_threadingContext.DisposalToken).ConfigureAwait(false));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You could get rid of the .ConfigureAwait's here since we're in a definitely JTF safe situation. Our analyzers might not like it though. (Wonder if we should teach them to ignore that in JTF.Runs...)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done.


public bool IsSupportedTheme()
=> IsSupportedTheme(GetThemeId());
=> _threadingContext.JoinableTaskFactory.Run(() => IsSupportedThemeAsync(_threadingContext.DisposalToken));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Use of _threadingContext.DisposalToken seems a bit odd here, since it means whoever is calling IsSupportedTheme() might get it potentially cancelled out from underneath them. Can the caller pass through a token?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

that's a good point let me see.

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.

4 participants