Npgsql LISTEN线程崩溃服务器

时间:2014-12-18 19:02:24

标签: multithreading c#-4.0 thread-safety npgsql

我有一个长期运行的PostgreSQL函数。为简单起见,这样的事情:

CREATE FUNCTION pg_function()
RETURNS void
AS
$$
BEGIN
    PERFORM pg_notify('channel1', 'pg_function() started.');

    PERFORM pg_sleep(5);------PERFORM task1();-----------------------------------------
    PERFORM pg_notify('channel1', 'Task1 payload.');

    PERFORM pg_sleep(5);------PERFORM task2();-----------------------------------------
    PERFORM pg_notify('channel1', 'Task2 payload.');    

    PERFORM pg_sleep(5);------PERFORM task3();-----------------------------------------
    PERFORM pg_notify('channel1', 'Task3 payload.');    

    PERFORM pg_notify('channel1', 'pg_function() completed.');
END;
$$
LANGUAGE "plpgsql";

在C#上,我有:

public bool listening;
public void PgFunction()
{
    this.listening = true;

    ThreadStart listenerStart = delegate
    {
        using (NpgsqlConnection connection = new NpgsqlConnection(this.connectionString))
        {
            connection.Open();
            connection.Notification += Listen;

            using (NpgsqlCommand listenChannel1 = new NpgsqlCommand("LISTEN channel1;", connection))
            {
                listenChannel1.ExecuteNonQuery();
            }

            while (this.listening)
            {
                using (NpgsqlCommand pollingCommand = new NpgsqlCommand("SELECT 0;", connection))
                {
                    pollingCommand.ExecuteNonQuery();
                }

                Thread.Sleep(5000);
            }
        }
    };

    Thread listenerThread = new Thread(listenerStart) { IsBackground = false };
    listenerThread.Start();

    ThreadStart pgFunctionThreadStart = () => ExecuteNonQuery(new NpgsqlCommand("SELECT pg_function();"));

    pgFunctionThreadStart += () =>
    {
        Thread.Sleep(5000);
        this.listening = false;
    };

    Thread pgFunctionThread = new Thread(pgFunctionThreadStart) { IsBackground = true };
    pgFunctionThread.Start();
}

private void Listen(object sender, NpgsqlNotificationEventArgs e)
{
    string payload = e.AdditionalInformation;
    //SignalR stuff here
}

当我运行程序调试时,此代码可以正常工作。但是,当它在IIS服务器上进行测试或使用Visual Studio 2013集成的IIS进行浏览时,应用程序崩溃了。由于我对C#中的任务和线程知之甚少,我想知道我在这里做错了什么?请指教。

修改

再次调试时,我遇到了一个N​​pgsqlException,偶尔会发生一次:

Additional information: Cannot write to a BufferedStream while the read buffer is not empty if 
the underlying stream is not seekable. Ensure that the stream underlying this BufferedStream 
can seek or avoid interleaving read and write operations on this BufferedStream.

0 个答案:

没有答案