Closed davkean closed 1 year ago
Are you sure that is the issue? (not a visual studio/dot net wiz)
Is calling UserLocalDataPath on the AsycPackage while not on the UI thread the actual issue? So just capturing UserLocalDataPath
from the package while in the InitializeAsync
will fix it? I suppose this is a dead lock kind of scenario? (tried reading the stack trace, assumed lower is higher up in the call chain, and the highest is the active method stuck)
I would have guessed that the issue might be slow network speeds, because the extension downloads assets from the web to be used by the extension. Which is why I was sure to not run that download work on the UI thread. So that might be causing the issue because it tries to get the path while outside the UI thread? Perhaps it might be because it takes forever for it to download or it could be like you said and is an issue with deadlock or something.
Any insights are welcome.
@davkean
The problem is that UserLocalDataPath under the covers performs a hidden thread switch to the UI thread, in times of high UI thread usage (such as solution load), these calls can back up waiting for access, consuming large amounts of thread pool threads in the meantime. This prevents other features from using these threads.
In the above dump, we had 269 threads (ie calls) backed up all waiting for access to the UI thread. A typical VS instance should have only as many thread pool threads as there are logical CPUs (4 on a 4-core machine, 8 on a 4-core with hyper-threading for example), but this extension is consuming 269 of them (!), at which point VS would have slowed to a crawl and would very unpleasant to use.
By caching and reading UserLocalDataPath once upfront, this thread switch is avoided and removes the backup of threads.
Towards the top of the stack, you can see a call to CThreadAwareServiceProvider::QueryService, that is performing the thread switch to grab a "service" from the UI thread, so its not network related.
Thanks for bringing this to my attention. Pretty sure I addressed the issue. Ran the code that accesses UserLocalDataPath
on the UI thread, captured it for reuse later on.
Thanks, @Unthrottled looks good.
Hey folks, I'm from the Visual Studio team and our performance telemetry has caught an issue in this extension where it is causing Visual Studio unresponsivess by consuming large number of thread pool threads in the wild.
Over the past 90 days, we've captured 14 instances of this, with an average of 37 threads, but upwards of 269 threads.
In one of the dumps we captured, I see that the following stack is consuming 269 threads trying to retrieve UserLocalDataPath.
To resolve this, please capture UserLocalDataPath once on the UI thread in https://github.com/doki-theme/doki-theme-visualstudio/blob/main/doki-theme-visualstudio/doki_theme_visualstudioPackage.cs#L54, and then pass that through to the components that need it.