如何在项目中禁止`async void`并触发构建错误或警告?
如何在项目中禁止
async void并触发构建错误或警告? 完全懂你的痛!async void在ASP.NET Core里搞崩整个进程、在MSTest里搞出各种诡异的测试问题,简直是异步代码里的隐形炸弹。既然你们完全不用它(连事件处理器都没有),直接从构建层面禁用绝对是最稳妥的方案,下面给你几个实操性强的办法:
方法一:用AsyncFixer分析器(最快上手)
这个第三方分析器专门盯异步代码的坑,其中就包含禁止async void的规则,几步就能搞定:
- 给所有需要禁用的项目安装NuGet包:
Install-Package AsyncFixer - 在项目的
.editorconfig文件(如果没有就新建一个)里添加规则配置,把违规级别设为Error(直接阻断构建):
如果是多项目解决方案,建议在根目录放一个统一的# 禁止async void方法,触发构建错误 dotnet_diagnostic.AsyncFixer001.severity = error.editorconfig,所有项目自动继承,不用逐个配置。
方法二:自定义Roslyn分析器(更灵活可控)
要是不想依赖第三方包,自己写个极简的分析器也不难,核心就是检测方法签名里的async + void组合:
大概的核心代码逻辑(简化版):
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using System.Collections.Immutable; [DiagnosticAnalyzer(LanguageNames.CSharp)] public class AsyncVoidAnalyzer : DiagnosticAnalyzer { private static readonly DiagnosticDescriptor Descriptor = new( id: "AV0001", title: "禁止使用async void", messageFormat: "方法 '{0}' 使用了async void,禁止该写法", category: "异步代码规范", defaultSeverity: DiagnosticSeverity.Error, isEnabledByDefault: true); public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Descriptor); public override void Initialize(AnalysisContext context) { context.EnableConcurrentExecution(); context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.RegisterSymbolAction(AnalyzeMethod, SymbolKind.Method); } private static void AnalyzeMethod(SymbolAnalysisContext context) { var methodSymbol = (IMethodSymbol)context.Symbol; // 检测是否是async且返回void的方法 if (methodSymbol.IsAsync && methodSymbol.ReturnType.SpecialType == SpecialType.System_Void) { context.ReportDiagnostic(Diagnostic.Create(Descriptor, methodSymbol.Locations[0], methodSymbol.Name)); } } }
把这个分析器打包成NuGet包或者直接嵌入项目,就能完全自定义规则的ID、提示信息和违规级别,彻底掌控禁用逻辑。
方法三:利用项目规则集文件(适合大型解决方案)
如果你的项目已经在用自定义规则集(.ruleset),可以直接在里面添加规则配置:
- 打开规则集文件,找到AsyncFixer的
AsyncFixer001规则(如果是自定义分析器就找你自己定义的规则ID) - 把规则的Action设为
Error,保存后所有引用该规则集的项目都会强制执行禁用。
额外提醒
针对你的MSTest场景:禁用async void后,测试方法必须改成async Task,这样测试框架才能正确等待异步操作完成,彻底解决测试时的“诡异行为”——这正好符合你的需求。
备注:内容来源于stack exchange,提问作者Branko Dimitrijevic
相关产品推荐
相关产品推荐

