Блокирующий обработчик событий

#c# #npgsql

#c# #npgsql

Вопрос:

Имеющий следующий код:

 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, вывод:

Начало полученного уведомления

Получено уведомление об окончании

Начало полученного уведомления

Получено уведомление об окончании

Это показывает, что событие 2 запускается только после завершения 1-го события.

В обработчике событий мне нужно запустить некоторый код, пока не сработает следующее событие:

 var stream = Stream.CreateFilteredStream();
...
stream.StartStreamMatchingAllConditions(); // blocking
  

Когда срабатывает следующее событие, мне нужно вызвать stream.StopStream() (для завершения предыдущего потока), прежде чем запускать тот же код в обработчике.

Проблема в том, что из-за stream.StartStreamMatchingAllConditions() блокировки следующее событие не запускается, поэтому остановить предыдущий поток невозможно.

Есть ли какой-нибудь способ добиться этого?

Ответ №1:

Если я правильно понимаю запрос, вы хотите иметь возможность обработать следующее уведомление до завершения обработки первого уведомления. Это означало бы, что ваш код обработчика событий выполнялся в отдельном потоке от того, который отправляет события из Npgsql — это не так.

Однако вы можете легко добиться этого в своем коде, самостоятельно запустив код обработки в отдельном потоке:

 conn.Notification  = (o, e) =>
{
    Task.Run(() =>
    {
        Console.WriteLine("Received notification begin");
        Thread.Sleep(10000);
        Console.WriteLine("Received notification end");
    });
};