C# Parallel.For 和 Oracle 数据库访问 - 内存异常

C# Parallel.For and Oracle database access - memory exception

我正在编写一些代码,我想在 Parallel.For 循环内访问 Oracle 数据库。循环将 运行 持续几分钟,然后导致错误:

"Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

没有内部异常。在我的 Parallel.For 循环中,我正在创建一个打开的数据库连接作为本地对象。我的代码如下所示:

static void CheckSinglePath(Path p)
{    
     string sqlBase = "select * from table where hour = #HOUR#";
     Parallel.For (1, 24, i =>
     {        
            DBManager localdbm = new DBManager();                
            string sql = sqlBase;
            sql = sql.Replace("#HOUR#", i.ToString());
            OracleDataReader reader = db.GetData(sql);
            if (reader.Read())
            {
               //do some stuff
            }
            reader.Close();
     });
}

class DBManager
{
    OracleConnection conn;
    OracleCommand cmd;
    public DBManager()
    {
        string connStr = "blahblahblah;Connection Timeout=600;";
        conn = new OracleConnection(connStr);            
        conn.Open();
        cmd = conn.CreateCommand();
    }

    public OracleDataReader GetData(string sql)
    {
        cmd.CommandText = sql;
        return cmd.ExecuteReader();//EXCEPTION HERE!
    }        
}

我做错了什么?如何创建 24 个并行 Oracle 连接来处理数据?我猜这里发生了某种我不完全理解的竞争条件或内存泄漏,因为它似乎来自 OracleConnection 对象内部。数据库连接不是线程安全的吗?我尝试更改连接字符串以使用连接池,但没有任何改变。

内存问题总是由错误的资源使用引起的。循环退出后您没有正确释放连接。

您需要实施 IDisposable interface and after that you need rewrite your code in such manner with using keyword:

// dispose the connection after command finished
using (var localdbm = new DBManager())
{            
    var sql = sqlBase;
    sql = sql.Replace("#HOUR#", i.ToString());
    using (var reader = db.GetData(sql))
    {
        if (reader.Read())
        {
           //do some stuff
        }
        // no need to close reader
        // as it's being disposed inside using directive
    }
}