首页 文章

使用VB / C#Diagnostic Analyzer / CodeFix / AutoUpdate多个.vsix会导致性能问题吗?

提问于
浏览
0

我正在实施一个系统,该系统将实现代码质量作为内部质量措施的一部分 . 我用两种可能的实现方式构建了系统,如下所示:

Implementation 1: (Already implemented)

  • AutoUpdate扩展(存根)

  • C#CodeQualityPlugin(Roslyn C#Diagnostic Analyzer&Code Fix)

  • VB CodeQualityPlugin(Roslyn VB诊断分析器和代码修复)

AutoUpdate功能通过验证其版本号来检查自身和其他CodeQuality插件的任何更新 . 一旦更新了CodeQuality插件,它将停止接下来7天的更新 .

这是我目前的实现想法,但是由于此实现中与扩展数量相关的可能性能问题以及可能存在Visual Studio对其使用/性能的限制(如团队所述),因此停止开发

Implementation 2: (Suggested)

  • C#CodeQualityPlugin(Roslyn C#Diagnostic Analyzer,Code Fix,AutoUpdate)

  • VB CodeQualityPlugin(Roslyn VB诊断分析器,代码修复,自动更新)

在此,更新功能被单独触发并保持单一责任理念 .

我不确定AutoUpdate项目(使用菜单命令模板)和C#/ VB CodeFix / DiagnosticAnalyzer项目(Roslyn模板)是否可以共存?

Implementation 3: (One of the opinion)

  • CodeQualityPlugin(Roslyn C#/ VB诊断分析器,代码修复,自动更新)

我甚至不确定这三个是否可以在单个vsix中共存 .

所以我的问题可能是上述三种场景中的性能问题,以及我们如何将基于Roslyn模板开发的插件实现为visual studio的普通菜单命令模板扩展 .

---EDIT--- 总结要求如下

  • Coexistence :VSPackage扩展(用于扩展Visual Studio的shell命令组件)和Managed Extensibility Framework / MEF扩展(用于自定义和扩展编辑器以包含Roslyn DiagnosticAnalyzer / CodeFix),应该共存于

  • 单VSIX

  • 最多2个VSIX

  • Performance :共存不应影响性能,VSPackage扩展所处理的AutoUpdate不应创建冗余服务调用 .

2 回答

  • 1

    没有 .

    你可以拥有的唯一真正的“性能问题”是将C#和VB放在同一个程序集中(注意,而不是VSIX),这意味着当我们必须加载一个时,我们加载其他组件 .

    从MEF的角度来看,我们只得到一个出口清单:我们不知道它们来自哪个VSIX,而且即使我们想要也很难弄清楚 . 那么你把东西放进去的VSIX根本不重要:根据对你的用户有意义的东西来划分它们 .

  • 2

    Roslyn和VSIX包装的注意事项:

    作为mentionedSrivatsn

    • 引用 Microsoft.CodeAnalysis.CSharpMicrosoft.CodeAnalysis.VisualBasic 的扩展名将会

    • 即使我们尝试打开C#项目,也加载两个编译器,这并不理想 .

    • 如果我们必须分析符号 ISymbolAnalyzer ,在那里只分析符号而不是语法节点,那么我们应该采用一个与语言无关的分析器 . 这意味着我们不必引用任何C#/ VB dll(即使Microsoft正在考虑实现更多与语言无关的分析器) . 包括两个导出属性 - 每种语言一个,这些属性告诉VS实例化并在解决方案中包含相应的语言时调用这些分析器 .

    • 编译作为一个进程在编译完成后离开内存,但由于几乎每次击键都会发生编译,如果分析器同时引用c#和VB,它会将两个编译器都带入内存 . 由于存在持久性特征,如果解决方案下存在大型项目,则可能会出现问题(这是我的典型 生产环境 方案)

    • 在调用相应的语法方法时,或者在导出的分析器实例化时(通过提及相应的语言用例再次通过MEF导出属性进行过滤),是否加载编译器存在混淆,因为他还提到了if引用这两种语法节点的方法可能会使JIT编译并加载dll .

    • 链接到菜单命令的任何分析器都是VS特定的,如果它们链接到项目,那么它也将参与构建,甚至在VS之外通过MSBuild

    • VSIX应该能够导出多个组件以扩展这两个扩展点 .

    mentionedVSadov

    • 语法树数据结构的持久性以及在每次击键时重新进行分析的需要(delta-compilation:这是Srivatsn编译的意思)使他们设计了红绿树方法,这有助于delta-的性能汇编 .

    mentionedSLaks

    • MEF导出无论是否打包在单个VSIX中都没有任何区别(但应注意,将两种类型分析器组合到一个MEF导出的组件中存在性能问题)

    mentionedKevin Pilch

    • 虽然这些程序集的打包位置并不重要,除非它们在涉及特定于语言的引用时是独立的 .

    • 如果分析器同时引用C#和VB特定的Roslyn程序集并且这些编译器程序集很大,则将保留虚拟内存

    • 性能问题是磁盘加载和JIT成本(如果没有编译且只有引用,我不确定JIT成本是多少),但由于保留了地址空间,VS中可能存在问题(我不确定这将是一个什么问题 . )

    • 据他所说,微软所做的是创建三个项目来解决这个问题(据Srivatsn称,微软仍在尝试使用与语言无关的分析器)

    • 共享(其中没有特定语言的二进制文件)

    • C#特定(共享库)

    • VB特定(共享库)

    • 如果没有引用特定于语言的二进制文件,并且MEF导出是否适当地归因于 ContentTypeLanguageName 那么上述问题可以解决

    • 我们可以将其他程序集捆绑到一个VSIX中(通过在其中嵌入其他项目),VS将独立加载每个程序集

    最终实施:

    所以最后我和我的团队讨论后得出如下结论

    • 通过在其中嵌入以下项目来实现单个VSIX实现

    • 更新插件

    • 检查过去7天是否有更新

    • 然后通过JSON请求检查服务器端插件的版本号

    • 然后从服务器下载插件,将下载日期存储在VS设置中进行初始检查

    • 禁用以前的插件

    • 卸载以前的插件

    • 安装新插件

    • 此功能在触发时触发

    • VS加载

    • 手动菜单命令(应该覆盖下载日期检查)

    • C#插件

    • 实现并仅引用C#的规则

    • VB插件

    • 实现并仅引用VB的规则

相关问题