SQL Server CLR中是否存在内存泄漏或某些错误



有我的代码,这个方法通常在多个线程调用它时抛出异常,有时抛出threadAbortException,有时抛出内存不足或内存被SQL Server收集,还有另一个类用于锁定List,它存储访问的客户端信息,SQL Server通常会清除它或释放CLR程序集,我不知道为什么。如果你有CLR经验,你能帮我吗?谢谢。我的代码如下:

private static bool QueryResultSet(string value)
{
    if(string.IsNullOrEmpty(value))
    {
        return false;
    }
    int returnValue;
    bool result;
    if (!Int32.TryParse(value, out returnValue))
    {
        return false;
    }
    result = true;
    try
    {   
        using (SqlDataReader dr = SqlHelper.ExecuteReader(SqlHelper.connectionString,
            CommandType.Text,
            string.Format("SELECT {0} AS Result", returnValue)))
        {
            SqlContext.Pipe.Send(dr);
        }
    }
    catch (Exception ex)
    {
        _logger.Error(ex);
        result = false;
    }
    return result;
}

使用SqlHelper.ExecuteReader(conectionString...)时,默认情况下会出现内存泄漏。当使用连接字符串而不是连接时,ExecuteReader()方法在设计上出现错误。由于连接是在方法内部而不是外部进行的,因此无法正确使用它,因此在使用读取器后,您无法手动关闭连接。因此,首先,在using()语句中创建连接,然后将其传递给SqlHelper.ExecuteReader(_theConnection..)方法。

这是ApplicationBlocks的相同功能。数据来源:

    /// <summary>
    /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string 
    /// using the provided parameters.
    /// </summary>
    /// <remarks>
    /// e.g.:  
    ///  SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24));
    /// </remarks>
    /// <param name="ConnectionString">a valid connection string for a SqlConnection</param>
    /// <param name="commandType">the CommandType (stored procedure, text, etc.)</param>
    /// <param name="commandText">the stored procedure name or T-SQL command</param>
    /// <param name="commandParameters">an array of SqlParamters used to execute the command</param>
    /// <returns>a SqlDataReader containing the resultset generated by the command</returns>
    public static SqlDataReader ExecuteReader(string ConnectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters)
    {
        //create & open a SqlConnection
        SqlConnection cn = new SqlConnection(ConnectionString);
        cn.Open();
        try
        {
            //call the private overload that takes an internally owned connection in place of the connection string
            return ExecuteReader(cn, null, commandType, commandText, commandParameters,SqlConnectionOwnership.Internal);
        }
        catch
        {
            //if we fail to return the SqlDatReader, we need to close the connection ourselves
            cn.Close();
            throw;
        }
    }

正如我们从上面的确切函数中看到的那样,他们在该函数内部创建连接,然后创建读取器并返回它

连接从未关闭。

如果我们使用这个方法,那么连接池最终会溢出,因为这个函数默认情况下会产生泄漏。因此,不要通过传递连接字符串来使用此函数。相反,您在外部打开一个连接,将其传递给SqlHelper.ExecuteReader(),对读取器执行操作,关闭读取器,然后关闭连接。

查看您功能的修改代码:

private static bool QueryResultSet(string value)
{
    if(string.IsNullOrEmpty(value))
    {
        return false;
    }
    int returnValue;
    bool result;
    if (!Int32.TryParse(value, out returnValue))
    {
        return false;
    }
    result = true;
    using (SqlConnection connection = new SqlConnection(SqlHelper.connectionString)) 
    {
        try
        {
            using (SqlDataReader dr = SqlHelper.ExecuteReader(connection,
                CommandType.Text,
                string.Format("SELECT {0} AS Result", returnValue)))
            {
                SqlContext.Pipe.Send(dr);
            }
        }
        catch (Exception ex)
        {
            _logger.Error(ex);
            result = false;
        }
        finally
        {
            // TODO: Here you can check if connection state is open before closing it
            conneciton.Close();
        }
    }
    return result;
}

相关内容

  • 没有找到相关文章

最新更新