Roslyn 提高IClassizer的性能

Roslyn 提高IClassizer的性能,roslyn,visual-studio-extensions,visual-studio-sdk,Roslyn,Visual Studio Extensions,Visual Studio Sdk,我正在创建Visual Studio 2017/2019扩展。我导出a是为了能够根据需要访问语义模型的内容更改某些C#语法节点的格式(我使用的是Roslyn)。这意味着确定是否对某个节点进行分类在计算上相对昂贵。一旦用户开始在VisualStudio中键入,每个键入的字符都会生成一个新的语义模型。这使得编码体验很糟糕 有没有办法告诉Visual Studio在决定调用我的分类器之前等待一段时间(例如200毫秒)?如果输入的一个字符与另一个字符之间的传递时间少于200毫秒,VisualStudio

我正在创建Visual Studio 2017/2019扩展。我导出a是为了能够根据需要访问语义模型的内容更改某些C#语法节点的格式(我使用的是Roslyn)。这意味着确定是否对某个节点进行分类在计算上相对昂贵。一旦用户开始在VisualStudio中键入,每个键入的字符都会生成一个新的语义模型。这使得编码体验很糟糕

有没有办法告诉Visual Studio在决定调用我的分类器之前等待一段时间(例如200毫秒)?如果输入的一个字符与另一个字符之间的传递时间少于200毫秒,VisualStudio将再等待200毫秒,然后再决定调用分类器。这意味着分类器将仅在用户空闲200毫秒后调用(不更改代码)。这将为使用扩展的开发人员提供更好的体验

IClassifier接口有一个ClassificationChanged事件,我可以使用它告诉Visual Studio某些跨度需要重新分类。我想用这个。第一次调用GetClassificationSpans时,我会返回一个空列表,然后在大约200毫秒后异步调用ClassificationChanged。但是似乎无法知道当前调用GetClassificationSpans是否是我最近调用ClassificationChanged的结果。IClassifier的合同甚至不能保证(据我所知),它将调用GetClassificationSpans,其跨度与我传递给ClassificationChanged的跨度相同。例如,如果它决定将跨度一分为二怎么办?或者将它与另一个跨度合并

我正在考虑的一个解决方案是手动监视当前文档中的更改(通过ITextBuffer.Changed事件),监视更改之间的时间,“启用”分类器(当我认为分类时间合适时),调用“ClassificationChanged”触发分类,然后“禁用”分类后的分类器


尽管此解决方案可能有效,但是否有一种干净的方法可以做到这一点?

告诉Visual Studio等待一段时间,等待System.Threading.Tasks.Task.Delay(100)?我们可以使用来管理源代码和glyph标记之间的关系。当引发ITextBuffer接口的事件(例如更改的事件)时,我们可以使用IClassiferAggregatorService接口获取标记器从中浇铸的相关IClassizer对象(GetClassifier方法)。