阻塞事件处理器
Blocking event handler
具有以下代码:
var conn = new NpgsqlConnection("...");
conn.Open();
conn.Notification += (o, e) =>
{
Console.WriteLine("Received notification begin");
Thread.Sleep(10000);
Console.WriteLine("Received notification end");
};
using (var cmd = new NpgsqlCommand("LISTEN query", conn))
{
cmd.ExecuteNonQuery();
}
while (true)
{
conn.Wait();
}
当我 运行 它从数据库 2 快速请求一个触发器时,输出是:
Received notification begin
Received notification end
Received notification begin
Received notification end
这表明第2个事件仅在第1个事件结束后触发。
在事件处理程序中,我需要 运行 一些代码直到下一个事件触发:
var stream = Stream.CreateFilteredStream();
...
stream.StartStreamMatchingAllConditions(); // blocking
当下一个事件触发时,我需要在 运行 在处理程序中使用相同的代码之前调用 stream.StopStream()
(以结束上一个流)。
问题是因为 stream.StartStreamMatchingAllConditions()
正在阻塞,下一个事件不会触发,所以无法停止上一个流。
有什么办法可以实现吗?
如果我对请求的理解正确,您希望能够在第一个通知处理完成之前处理下一个通知。这意味着您的事件处理程序代码 运行 在一个单独的线程中,与从 Npgsql 调度事件的线程不同 - 事实并非如此。
不过,您可以在自己的代码中轻松实现这一点,方法是 运行 您自己在单独的线程中处理代码:
conn.Notification += (o, e) =>
{
Task.Run(() =>
{
Console.WriteLine("Received notification begin");
Thread.Sleep(10000);
Console.WriteLine("Received notification end");
});
};
具有以下代码:
var conn = new NpgsqlConnection("...");
conn.Open();
conn.Notification += (o, e) =>
{
Console.WriteLine("Received notification begin");
Thread.Sleep(10000);
Console.WriteLine("Received notification end");
};
using (var cmd = new NpgsqlCommand("LISTEN query", conn))
{
cmd.ExecuteNonQuery();
}
while (true)
{
conn.Wait();
}
当我 运行 它从数据库 2 快速请求一个触发器时,输出是:
Received notification begin
Received notification end
Received notification begin
Received notification end
这表明第2个事件仅在第1个事件结束后触发。
在事件处理程序中,我需要 运行 一些代码直到下一个事件触发:
var stream = Stream.CreateFilteredStream();
...
stream.StartStreamMatchingAllConditions(); // blocking
当下一个事件触发时,我需要在 运行 在处理程序中使用相同的代码之前调用 stream.StopStream()
(以结束上一个流)。
问题是因为 stream.StartStreamMatchingAllConditions()
正在阻塞,下一个事件不会触发,所以无法停止上一个流。
有什么办法可以实现吗?
如果我对请求的理解正确,您希望能够在第一个通知处理完成之前处理下一个通知。这意味着您的事件处理程序代码 运行 在一个单独的线程中,与从 Npgsql 调度事件的线程不同 - 事实并非如此。
不过,您可以在自己的代码中轻松实现这一点,方法是 运行 您自己在单独的线程中处理代码:
conn.Notification += (o, e) =>
{
Task.Run(() =>
{
Console.WriteLine("Received notification begin");
Thread.Sleep(10000);
Console.WriteLine("Received notification end");
});
};