5

是否有一种编程方式来查找由 .Net 连接器/MySql.Data.dll 维护的与数据库的当前打开连接数?

我有兴趣在使用库的同一程序中收集这些信息。

4

2 回答 2

5

连接池在客户端执行。要访问它,您需要使用反射来访问 MySqlPoolManager 和 MySqlPool 类,它们都是 MySql.Data 程序集的内部。

从本质上讲,您需要使用反射来访问池。就是这样:

Assembly ms = Assembly.LoadFrom("MySql.Data.dll");
Type type = ms.GetType("MySql.Data.MySqlClient.MySqlPoolManager");
MethodInfo mi = type.GetMethod("GetPool", BindingFlags.Static | BindingFlags.Public);
var pool = mi.Invoke(null, new object[] { new MySqlConnectionStringBuilder(connString) });

你会注意到你必须传入一个MySqlConnectionStringBuilder对象。它为每个连接字符串创建一个单独的池,因此请使用您在应用程序中使用的相同连接字符串(它需要完全相同)。

然后,您可以访问私有池字段和属性(同样,使用反射),以获取您需要的信息。特别是,“可用”字段和“NumConnections”属性可能是您感兴趣的。还有“idlePool”(a Queue<>)和“inUsePool”(a List<>),您也可以访问它们,尤其是计数。

于 2013-02-19T17:53:56.567 回答
2

感谢Petes 对这个问题的回答另一个答案,我能够构建以下函数:

    /// <returns>totalAvailable, inUseCount, idleCount</returns>
    public int[] GetPoolStatsViaReflection(MySqlConnectionStringBuilder connectionStringBuilder)
    {
        var asm = typeof(MySqlConnectionStringBuilder).Assembly;
        var poolManagerType = asm.GetType("MySql.Data.MySqlClient.MySqlPoolManager"); // internal sealed
        var poolType = asm.GetType("MySql.Data.MySqlClient.MySqlPool"); // internal sealed

        var pool = poolManagerType.InvokeMember("GetPool", System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public, null, null, new object[] { connectionStringBuilder });

        const System.Reflection.BindingFlags nonPublicInstanceField = System.Reflection.BindingFlags.GetField | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
        var totalAvailable = (int)poolType.InvokeMember("available", nonPublicInstanceField, null, pool, new object[] { });
        // List<Driver>
        var inUsePool = (System.Collections.ICollection)poolType.InvokeMember("inUsePool", nonPublicInstanceField, null, pool, new object[] { });
        // Queue<Driver>
        var idlePool = (System.Collections.ICollection)poolType.InvokeMember("idlePool", nonPublicInstanceField, null, pool, new object[] { });

        return new[] {totalAvailable, inUsePool.Count, idlePool.Count};
    }
于 2018-06-15T08:51:21.333 回答