在将ASP.NET应用程序迁移到异步/等待模型时,我偶然发现了一个相当危险的场景。
情况是,我使方法async:,async Task DoWhateverAsync()
将接口中的声明更改为,Task DoWhateverAsync()
并希望编译器通过该Warning告诉我代码现在哪里出错了。好吧,运气不好。通过接口将对象注入的任何地方,都不会发生警告。:-(
这很危险。有什么方法可以自动检查返回任务的未等待的方法吗?我不介意太多警告,但我不想错过任何警告。
这是一个例子:
using System.Threading.Tasks;
namespace AsyncAwaitGames
{
// In my real case, that method just returns Task.
public interface ICallee { Task<int> DoSomethingAsync(); }
public class Callee: ICallee
{
public async Task<int> DoSomethingAsync() => await Task.FromResult(0);
}
public class Caller
{
public void DoCall()
{
ICallee xxx = new Callee();
// In my real case, the method just returns Task,
// so there is no type mismatch when assigning a result
// either.
xxx.DoSomethingAsync(); // This is where I had hoped for a warning.
}
}
}
最后,我们使用roslyn查找所有忽略Task或Task <>返回值的实例:
if (methodSymbol.ReturnType.Equals(syntaxNodeAnalysisContext.SemanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName)))
{
// For all such symbols, produce a diagnostic.
var diagnostic = Diagnostic.Create(Rule, node.GetLocation(), methodSymbol.ToDisplayString());
syntaxNodeAnalysisContext.ReportDiagnostic(diagnostic);
}
if (((INamedTypeSymbol) methodSymbol.ReturnType).IsGenericType && ((INamedTypeSymbol) methodSymbol.ReturnType).BaseType.Equals(syntaxNodeAnalysisContext.SemanticModel.Compilation.GetTypeByMetadataName(typeof(Task).FullName)))
{
// For all such symbols, produce a diagnostic.
var diagnostic = Diagnostic.Create(Rule, node.GetLocation(), methodSymbol.ToDisplayString());
syntaxNodeAnalysisContext.ReportDiagnostic(diagnostic);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句