是否可以将Npgsql函数与Parallel.For块一起使用?
这是我的例子,但我得到了异常“Backend发送了无法识别的响应类型:\ 0”
NpgsqlConnection PGconnexion = new NpgsqlConnection(...);
string SqlParallel = "";
int OID = -1;
Parallel.For(0, 100, i =>
{
SqlParallel = string.Format(@"INSERT INTO ParallelTest(Id) VALUES({0}) RETURNING OID;", i);
using (NpgsqlCommand PGcommandParallel = new NpgsqlCommand(SqlParallel, PGconnexion))
{
try { OID = (int)PGcommandParallel.ExecuteScalar(); }
catch (Exception ex) { Console.WriteLine(ex.Message); }
}
Console.WriteLine("Insert: {0} OID: {1}", i, OID);
});
和PostgreSql表架构
-- Table: paralleltest
-- DROP TABLE paralleltest;
CREATE TABLE paralleltest
(
id integer
)
WITH (
OIDS=TRUE
);
GRANT ALL ON TABLE paralleltest TO public;
答案 0 :(得分:4)
基督教!
与其他提供程序一样,Npgsql不是线程安全的。当您使用具有相同连接的多个线程时,您最终会遇到此问题。
为了使它工作,你必须在Parallel.For循环中放置创建连接的行:
string SqlParallel = "";
int OID = -1;
Parallel.For(0, 100, i =>
{
using (NpgsqlConnection PGconnexion = new NpgsqlConnection(...))
{
SqlParallel = string.Format(@"INSERT INTO ParallelTest(Id) VALUES({0}) RETURNING OID;", i);
using (NpgsqlCommand PGcommandParallel = new NpgsqlCommand(SqlParallel, PGconnexion))
{
try { OID = (int)PGcommandParallel.ExecuteScalar(); }
catch (Exception ex) { Console.WriteLine(ex.Message); }
}
Console.WriteLine("Insert: {0} OID: {1}", i, OID);
}
});
我在这里测试过,它运行正常。请尝试一下,如果您仍然遇到此更改的问题,请告诉我。 请注意,我使用了“using”子句,因此一旦块结束,连接就会关闭。
我希望它有所帮助。
答案 1 :(得分:1)
在Francisco Junior的帮助下,这里是线程安全解决方案。
Parallel.For(0, 100, i =>
{
string SqlParallel = string.Format(@"INSERT INTO ParallelTest(Id) VALUES({0}) RETURNING OID;", i);
using (NpgsqlConnection PGconnexionParallel = new NpgsqlConnection(string.Format("Server={0};Port={1};User Id={2};Password={3};Database={4};", PGHost, PGPort, PGUser, PGPassword, PGDatabase)))
{
PGconnexionParallel.Open();
using (NpgsqlCommand PGcommandParallel = new NpgsqlCommand(SqlParallel, PGconnexionParallel))
{
try
{
int OID = (int)PGcommandParallel.ExecuteScalar();
Console.WriteLine("SqlParallel: {0} OID: {1}", SqlParallel, OID);
}
catch (Exception ex) { Console.WriteLine(ex.Message); }
}
}
});