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
}
}
我正在编写一些代码,我想在 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
}
}