Codist
Codist copied to clipboard
Codist causing Visual Studio responsiveness issues
Hey folks, I'm from the Visual Studio performance team and our telemetry is showing that Codist is causing responsiveness issues in the wild by consuming large amounts of thread pool threads.
Over the past 21 days at times where Visual Studio's thread pool has been starved, we've captured the following data:
| Failure | Score | Cab Count | Threads 90th | Threads 50th | Avg Threads |
|---|---|---|---|---|---|
| Codist!Unknown | 16 | 4 | 28 | 5 | 12 |
In particular these lines are the problem: https://github.com/wmjordan/Codist/blob/f38f7e479dc5399f834988ffc9611bdb7b7c21ff/Codist/Taggers/CSharpTagger.cs#L240-L244
It appears that this code is attemping to monitor the specified CancellationToken, and when triggered, cancel the parsing. When it does this, however, it consumes a thread - and in the wild, we saw that this path consumed up to 28 threads at its worst.
Instead there's an easier way to monitor cancellation and avoid the thread starvation; use CancellationToken.Register. Do however, make note, that by default the call back will run in context of the code that triggers the cancellation. If that is unwanted, and you want to maintain the existing behavior, call Register(() => {...}, useSynchronizationContext: true).
Thanks Dave
Thank you for posting this issue. I will investigate into it and try to fix it.
@fitdev
Hi, my friend. You may be affected by this issue, I guess. Please try the recently uploaded beta and see whether it help mitigating this problem.
I think the reason causing this problem is because the WorkspaceChanged event listener has improperly caused the current editing document getting re-parsed--it tried to avoid that but failed if a project targets multiple frameworks or the file in edit is shared by multiple projects.
A terrible case will be:
- You have a shared project and a file in that project is opened and being edited.
- The project is share by N projects.
- In those N projects, they have several target frameworks, assuming that the average number of target frameworks is M.
- Once the opened file in the share project is edited,
WorkspaceChangedevent will be fired multiple times for the document instance in each project and each target framework and. - Almost each time, a new parser task is created. So the number can be nearly N*M-1 (except the current document in current target framework).
Let's say that the shared project is referenced by 7 projects, and each of those projects targets 4 frameworks. An edit of the file in the shared project can raise up to 7*4-1=27 parser tasks and each of them can take a thread sometimes. Thus the thread pool gets starved quickly.
The recent beta should have this fixed.
Thank you for your suggestion! Fortunately I was not affected by this because while I do have some shared projects - they are only shared between 2 more projects and each targets only a single framework, so I never noticed the slowdowns.
Hi fitdev, thank you for your reply.
I wondered, who was the owner of the 28 mentioned in davkean's comment.
Anyway, please help test the latest beta and see whether it behaves OK.
Will do and let you know if I encounter any issues.
I wondered, who was the owner of the 28 mentioned in davkean's comment.
It certainly wasn't me :)
Version 6.5.3 that was released just now should have this issue completely fixed. @davkean Please reopen this issue if the problem persists.
Thanks!