読者です 読者をやめる 読者になる 読者になる

もなかアイスの試食品

「とりあえずやってみたい」そんな気持ちが先走りすぎて挫折が多い私のメモ書きみたいなものです.

【C#】NpgsqlでPostgreSQLのNotifyを受信する

以前、PythonでNotifyを受信する方法を書いた

monakaice88.hatenablog.com

C#のほうが個人的に利用することが多いのでC#版を書いてみた

環境

  • .NET Framework 4.5
  • 追加NuGetパッケージ
    • Microsoft.Extensions.Logging(1.1.0)
    • Microsoft.Extensions.Logging.Abstractions(1.1.1)
    • Npgsql(3.2.1)
    • System.Threading.Tasks.Extensions(4.3.0)

ソースコード

NpgsqlでNotifyを受信するサンプル

実行結果

C#実行時

f:id:monakaice88:20170328125306p:plain

Notify実行

f:id:monakaice88:20170328125323p:plain

C# Notify受信

f:id:monakaice88:20170328125351p:plain

ハマった点

既にNotifyの受信用にコネクションを開いているので、そのコネクションを使用して(サンプルコードだと【listenConnection】)、別のSQLを実行しようとすると例外が発生する。

以下がコード例

【NpgsqlCommand( “SELECT test;”, listenConnection )】後の【command.ExecuteReader()】でコケる

using ( NpgsqlConnection listenConnection = new NpgsqlConnection( builder.ConnectionString ) )
{
    listenConnection.Open();
    listenConnection.Notification += ( sender, e ) =>
    {
        Console.Out.WriteLine( "Recieve NOTIFY!" );
        using ( NpgsqlCommand command = new NpgsqlCommand( "SELECT test;", listenConnection ) )
        {
            command.ExecuteReader();
        }
    };

    using ( NpgsqlCommand command = new NpgsqlCommand( "LISTEN test;", listenConnection ) )
    {
        command.ExecuteNonQuery();
    }

    listenConnection.Wait();
}

例外のメッセージ

The connection is already in state ‘Waiting’

この例外は、Npgsqlから投げられる例外。

コネクションインスタンスの使い回しを避けて、新規にインスタンスを生成しないといけないみたい(Waitメソッドを呼び出したコネクションに限るかも・・・)