Visual studio 2015 Visual Studio 2015中的GetClassificationSpans没有';我什么也不退
我有一个tagger(ITagger的子类),我试图调用GetClassificationSpans,这样我就可以使用分类查找注释,并使用标记格式化。这在Visual Studio 2013中起作用,但现在在Visual Studio 2015中运行它时,GetClassificationSpans总是返回一个空列表-即使我在调试器中检查了跨度,并且它肯定会传递一个带有注释的跨度 有人知道2015年调用GetClassificationSpans可能会发生什么变化吗 顺便说一句:我通过在标记器提供程序(ITaggerProvider的子类)中导入IClassiferAggregatorService并将其传递给标记器的构造函数来获得分类器:Visual studio 2015 Visual Studio 2015中的GetClassificationSpans没有';我什么也不退,visual-studio-2015,visual-studio-extensions,vspackage,visual-studio-sdk,Visual Studio 2015,Visual Studio Extensions,Vspackage,Visual Studio Sdk,我有一个tagger(ITagger的子类),我试图调用GetClassificationSpans,这样我就可以使用分类查找注释,并使用标记格式化。这在Visual Studio 2013中起作用,但现在在Visual Studio 2015中运行它时,GetClassificationSpans总是返回一个空列表-即使我在调试器中检查了跨度,并且它肯定会传递一个带有注释的跨度 有人知道2015年调用GetClassificationSpans可能会发生什么变化吗 顺便说一句:我通过在标记器提
[import]
IClassifierAggregatorService aggregator;
然后,我在聚合器上的标记器中使用以下调用,该聚合器是我从提供商处获得的:
IList<ClassificationSpan> lstClassifiers = aggregator.GetClassifier(span.Snapshot.TextBuffer).GetClassificationSpans(span);
IList lstClassifiers=aggregator.GetClassifier(span.Snapshot.TextBuffer).GetClassificationSpans(span);
正如我所说,分类器列表总是空的。与VS2013中运行的代码完全相同。我似乎在网上找不到任何提及VS2015中任何可能导致这种情况的变化的内容
谢谢,好的。在尝试了不同的事情之后,似乎出现了几个问题:
希望这能帮助遇到相同问题的人。因此,一般来说,ITagger API并不要求标记器返回“真实”信息。相反,它是一个API,返回“您当时拥有的任何信息”。如果给您带来麻烦的缓冲区是C#或VB缓冲区,那是因为在VS2015中,我们将Roslyn中的所有内容都移动为异步,因此在重新计算数据之前,对GetClassificationSpans/GetTags的调用可能不会返回任何内容。有一个新的API,IAccurateTagger,它的存在是为了请求标记器提供“真实”数据,尽管这不是您希望在文本缓冲区更改中运行的东西,因为这样会降低性能 如果您试图在VS2015中查找注释,而让您感到困惑的文件是C#或VB缓冲区,那么最好调用Roslyn API,它可以为您提供所需的直接语法树数据。如果它是一种不同类型的缓冲区,您至少最好调用IAccurateTagger,但由于性能的影响,请尽可能小心地尝试这样做
(此外,如果您试图构建一个在键入时自动格式化的扩展,那么使用分类标记器将给您带来其他麻烦。VS2013中存在一些错误,您必须解决在标记更改期间调用C时,C会给出过时标记的问题。)我遇到了同样的问题,尽管是在不同的上下文中。从我的谷歌搜索中,看起来他们已经改变了分类器,所以它们被懒散地初始化了。。。我猜
GetClassificationSpans()
不会强制初始化它们。MSFT仍然认为这是一个bug,所以你可能想投票表决这个问题
一个潜在的解决方法(如MSFT所建议的)是切换到使用TagAggregator
而不是iclassizer
。因此,不是:
var service = container.GetService<IClassifierAggregatorService>();
var classifier = service.GetClassifier(textView.TextBuffer);
var spans = classifier.GetClassificationSpans(new SnapshotSpan(...));
var service=container.GetService();
var分类器=service.GetClassifier(textView.TextBuffer);
var span=classifier.getClassificationspan(新快照span(…);
你可以这样写:
var service = container.GetService<IViewTagAggregatorFactoryService>();
var aggregator = service.CreateTagAggregator<IClassificationTag>(textView);
var tags = aggregator.GetTags(new SnapshotSpan(...)));
var service=container.GetService();
var aggregator=service.CreateTagAggregator(textView);
var tags=aggregator.GetTags(新快照范围(…));
这将返回一个
IMappingTagSpan
列表,而不是ClassificationSpan
列表,因此使用它们的方式略有不同。但底层数据似乎基本相同——也就是说,您可以得到每个词汇元素的分类和跨度。虽然有一些细微的差别(请参见VS Connect上的说明),但结果对于我的应用程序来说已经足够好了。在SDK DLL的不同版本之间移动不应该真的产生影响——一旦在Visual Studio中实际运行,您仍然会调用相同的代码。