有没有办法在SqlConnection上检测开放阅读器?

mar*_*ard 9 c# sql-server

我在我正在处理的应用程序中收到错误"不允许新事务,因为还有其他线程正在运行".它在重构期间出现,特别是在创建测试套件期间.

我从环顾四周意识到这意味着我在创建事务时可能还有一个数据阅读器仍处于打开状态,但它是一个复杂的应用程序,对我来说问题不明显.因此,我希望能够找出读者连接到有问题的SqlConnection的内容.

理想情况下,我希望能够在Visual Studio中添加一个监视,然后在调试模式中单步执行以查看连接的读取器的数量何时发生变化.

有没有办法做到这一点?我在C#工作.

提前致谢.

马丁

mar*_*ard 8

唷!我现在对Reflection有更多的了解!

对于其他寻找答案的人来说,这是一个返回SqlConnection上数据读取器数量的方法.

public static int CountConnectedReaders(SqlConnection conn)
{
    int readers = 0;
    Type t = conn.GetType();
    MemberInfo[] minf = t.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance);
    for (int i = 0; i < minf.Length; i++)
    {
    if (minf[i].Name == "get_InnerConnection")
    {                    
        MethodInfo methinf = (MethodInfo)minf[i];

        object result = methinf.Invoke(conn, new object[0]);

        PropertyInfo[] pinfs = result.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Instance);
        foreach (PropertyInfo pinf in pinfs)
        {
        if (pinf.PropertyType.Name == "DbReferenceCollection")
        {
            object dbrc = pinf.GetValue(result, new object[0]);
            if (dbrc == null) readers = 0;
            else
            {
            MemberInfo[] dbrcInfs = dbrc.GetType().GetMembers(BindingFlags.NonPublic | BindingFlags.Instance);
            foreach (MemberInfo dbrcInf in dbrcInfs)
            {
                if (dbrcInf.Name == "_dataReaderCount")
                {
                FieldInfo finf = (FieldInfo)dbrcInf;
                readers = (Int32) finf.GetValue(dbrc);
                }
            }
            }
        }
        }
    }
    }

    return readers;
}
Run Code Online (Sandbox Code Playgroud)

有趣的是,在我的问题代码中使用这个表明当我得到"不允许新事务,因为有其他线程正在运行"错误时,连接上没有数据读取器,所以回到绘图板(或至少另一个SO问题)接着就,随即.