我正在尝试编写一个代码分析器,用于检查是否有任何未关闭的IDataReaders。
我已经看过这个问题,但它没有解释如何实现。我也试图阅读GitHub链接中的文档,但英语太复杂了,我不知道如何找到所有类型为IDataReader的实例,并验证在该类型的任何变量超出作用域之前是否调用了close()方法。
我尝试在Visual Studio中创建具有代码修复的Analyzer项目,我尝试在我的类的Initialize方法中注册操作上下文(该类扩展自类型
我希望找到所有持有类型IDataReader的变量出现的引用,确保在该变量失去作用域之前调用close方法。
以下是我想要分析的代码示例。
我已经看过这个问题,但它没有解释如何实现。我也试图阅读GitHub链接中的文档,但英语太复杂了,我不知道如何找到所有类型为IDataReader的实例,并验证在该类型的任何变量超出作用域之前是否调用了close()方法。
我尝试在Visual Studio中创建具有代码修复的Analyzer项目,我尝试在我的类的Initialize方法中注册操作上下文(该类扩展自类型
DiagnosticAnalyzer
),如下所示: [DiagnosticAnalyzer(LanguageNames.CSharp)]
public class DataReaderAnalyzerAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "DataReaderAnalyzer";
private static readonly LocalizableString Title = new LocalizableResourceString(nameof(Resources.AnalyzerTitle), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableString MessageFormat = new LocalizableResourceString(nameof(Resources.AnalyzerMessageFormat), Resources.ResourceManager, typeof(Resources));
private static readonly LocalizableString Description = new LocalizableResourceString(nameof(Resources.AnalyzerDescription), Resources.ResourceManager, typeof(Resources));
private const string Category = "DBConnectionCheck";
private static DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category, DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get { return ImmutableArray.Create(Rule); } }
public override void Initialize(AnalysisContext context)
{
context.RegisterOperationAction((operationContext) =>
{
((Microsoft.CodeAnalysis.CSharp.Syntax.AssignmentExpressionSyntax)((Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionStatementSyntax)operationContext.Operation.Syntax).Expression).Left
}
, OperationKind.ExpressionStatement);
}
}
我希望找到所有持有类型IDataReader的变量出现的引用,确保在该变量失去作用域之前调用close方法。
以下是我想要分析的代码示例。
class Program
{
static void Main(string[] args)
{
IDataReader reader = null;
try
{
Database db = DatabaseFactory.CreateDatabase("ApplicationConnection");
reader = GetDataReader(db);
while (reader.Read())
{
//Do somethig with the data here
}
reader.Close();
}
catch (Exception)
{
throw;
}
finally
{
if (reader != null && !reader.IsClosed)
{
reader.Close();
}
}
}
public static IDataReader GetDataReader(Database db)
{
DbCommand dbcmd = db.GetSqlStringCommand("some select statement to get data from oracle data base");
var reader = db.ExecuteReader(dbcmd);
return reader;
}
}
using
语句并不能真正关闭数据读取器(我使用的是与Oracle数据库通信的Microsoft Enterprise Library)。我的Web应用程序源代码有几千个方法,从DAL层返回IDataReader,重构一切对我来说不是一个选项,即使using语句突然开始工作也是如此。 - Vishweshwar KapseDbDataReader
,实际上所有读取器都是从它派生而来 - 请注意Dispose()
调用了Close()
- 实际上这就是Dispose()
做的全部。而且这里是OracleDataReader - 它并不改变Dispose()
。 - Marc GravellDataReaderWrapper
),但是Dispose()
仍然会执行if(!innerReader.IsClosed) { innerReader.Dispose(); }
- 所以它最终仍然会*调用Dispose()
,这将调用Close()
*。 - Marc Gravell