Hey I'm from the Visual Studio performance team, both ClaudiaIdePackage.InvokeChangeImage and ClaudiaIDE.InvokeChangeImage are both causing unresponsiveness in Visual Studio.
In the wild, these methods are consuming large amount of thread pool threads, causing other features inside Visual Studio to have responsiveness issues. At the worst case of this (see below image), the time it took for work to be queued to the thread pool to the time before it started running was nearly 12 minutes. This Visual Studio session that ran into this would have been completely unusable.
The reason this is occurring is because both methods are performing a synchronous thread blocking JTF.Run call from a background thread. In times where the UI thread is busy; such as downloading a symbol while debugging or loading a solution, these threads back up faster than the UI thread can respond causing the above issue. These JTF.Run calls should be replaced instead with a single ongoing task that is queued only once, and not blocked on.
Something similar to (I've not run or tested this):
❌ DO NOT call JoinableTaskFactory.Run from a background thread
JoinableTaskFactory.Run is for the UI thread. If called on a thread pool or background thread, it will block that thread (preventing it from taking on new work) until the async work has completed. This can cause thread pool starvation, reducing UI and feature responsiveness.
Avoid
Here JoinableTaskFactory.Run is being used to bridge synchronous property with an async method:
public bool IsOpen // Bad
{
get
{
JoinableTaskFactory jtf = …
// Blocks a thread
return jtf.Run(async () =>
{
var state = await GetOpenStateAsync();
return state == FrameState.Open;
});
}
}
private Task<FrameState> GetOpenStateAsync()
{
…
}
Instead
Instead, async should be plumbed all the way up the call chain:
public async Task IsOpenAsync() // Good
{
var state = await GetOpenStateAsync();
return state == FrameState.Open;
}
private Task<FrameState> GetOpenStateAsync()
{
…
}
Hey I'm from the Visual Studio performance team, both ClaudiaIdePackage.InvokeChangeImage and ClaudiaIDE.InvokeChangeImage are both causing unresponsiveness in Visual Studio.
In the wild, these methods are consuming large amount of thread pool threads, causing other features inside Visual Studio to have responsiveness issues. At the worst case of this (see below image), the time it took for work to be queued to the thread pool to the time before it started running was nearly 12 minutes. This Visual Studio session that ran into this would have been completely unusable.
The reason this is occurring is because both methods are performing a synchronous thread blocking JTF.Run call from a background thread. In times where the UI thread is busy; such as downloading a symbol while debugging or loading a solution, these threads back up faster than the UI thread can respond causing the above issue. These JTF.Run calls should be replaced instead with a single ongoing task that is queued only once, and not blocked on.
Something similar to (I've not run or tested this):
Here's our internal guidance on this:
❌ DO NOT call JoinableTaskFactory.Run from a background thread
JoinableTaskFactory.Run
is for the UI thread. If called on a thread pool or background thread, it will block that thread (preventing it from taking on new work) until the async work has completed. This can cause thread pool starvation, reducing UI and feature responsiveness.Avoid
Here
JoinableTaskFactory.Run
is being used to bridge synchronous property with an async method:Instead Instead, async should be plumbed all the way up the call chain: