3

今天我编写了以下代码,它与名为 Npgsql 的 PostgreSQL C# 库一起使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Npgsql;

namespace PostgreSQLNotificationsTest
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=postgres;Password=my_password;Database=helper_db.psql;SyncNotification=true"))
            {
                conn.Notification += OnNotification;
                conn.Open();
                using (var command = new NpgsqlCommand("listen notifytest;", conn))
                {
                    command.ExecuteNonQuery();
                }
                Console.ReadLine();
            };
        }

        private static void OnNotification(object sender, NpgsqlNotificationEventArgs e)
        {
            Console.WriteLine("event handled: " + e.AdditionalInformation);
        }
    }
}

然后我执行以下操作

createdb.exe -h 127.0.0.1 -p 5432 -U postgres -W helper_db.psql

psql.exe -h 127.0.0.1 -p 5432 -U postgres -W helper_db.psql

创建表助手(第一个文本主键,第二个整数);

CREATE OR REPLACE FUNCTION nf() RETURNS TRIGGER AS $$
BEGIN
    PERFORM pg_notify('notifytest', format('INSERT %s %s', NEW.first, NEW.second));
    RETURN NULL;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER any_after AFTER INSERT OR UPDATE OR DELETE ON helper FOR EACH ROW EXECUTE PROCEDURE nf();

插入辅助值('first', 10), ('second', 20);

在 C# 项目中,我得到以下输出:

处理的事件:插入前 10

没有“事件处理:插入秒 20”。只有当我执行“从助手中删除”之类的下一个操作时,我才会收到它。

为什么?

4

2 回答 2

2

除非您的客户端库支持检查网络套接字以获取缓冲数据,否则接收通知的唯一方法是触发套接字上的一些其他活动。

许多应用程序会定期发送一个空查询字符串 ( "") 来执行此操作。

如果客户端库支持它并且您没有使用 SSL,则可以在连接上定期调用某种 checkForNotifications() 函数。这在 PgJDBC 中是可能的,但我不知道 nPgSQL,所以我只能建议您查看相关文档。

于 2013-08-09T12:23:31.443 回答
1

更新(2015-02-27):这个错误已经在我们的 github 上的 master 分支中修复。请注意,master 分支是我们即将推出的 3.0 版本,可能有一些我们正在处理的错误。请试一试,让我知道它是否适合你。

这是 Npgsql 中的一个错误。我们正在努力修复它。检查此拉取请求以获取有关它的更多信息:https ://github.com/franciscojunior/Npgsql2/pull/46特别提交:https ://github.com/glenebob/Npgsql2/commit/98fd469048a20119755777ce3a8ffc4397f4a114

但是我们正在尝试另一种方法来解决这个问题。请注意,仅当您在很短的时间内发送多个通知时才会出现此问题。如果您在通知之间保持 1 或 2 秒的间隔,则它们会正确传递。

一旦我们得到修复,我会在这里更新我的答案。

对于此问题可能造成的所有不便,我们深表歉意。

于 2013-09-27T22:00:30.470 回答