Parallel.For与Npgsql一起使用吗?

时间:2014-03-08 11:08:07

标签: c# postgresql parallel-processing npgsql

是否可以将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;

2 个答案:

答案 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); }
                }
            }
        }); 
相关问题