私はParallel.For
ループ内のOracleデータベースにアクセスしたいコードに取り組んでいます。ループは数分間実行され、エラーが発生します。C#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
オブジェクトの内部から来ているようだから完全に理解できません。データベース接続はスレッドセーフではありませんか?接続プールを使用するために接続文字列を変更しようとしましたが、何も変更されませんでした。
はどのように不正なメモリのアクセスを引き起こす以前のリソースを配置していないでしょうか?メモリが長い間有効であるので、disposeを持たないものがあればこのようなバグを隠すでしょう。 – Voo
@Voo OPはいくつかの**の後にメモリエラー**を満たすため、管理されていないリソースが単にメモリ破損につながります – VMAtm
解放されたメモリは解放されたメモリにアクセスしません。管理されていないリソースを処分しないとリソースがなくなり、アクセスエラーは発生しません(メモリが不足し、アンマネージコードがmallocとcoの戻り値をチェックしない場合を除く) – Voo