Тайм-аут чтения сервера именованных каналов

При использовании C # NamedPipeServerStream, в случае, если клиент не отправляет никакой шаблон конца сообщения (например, \ r \ n, когда сервер читает с помощью ReadLine ()) NamedPipeServerStream Read будут ждать вечно, и никакие методы Abort () или Interupt () не будут работать с этим потоком.

Начиная с:
1) Stream.ReadTimeout не поддерживается для NamedPipeServerStream
2) Abort () или Interupt () не работают в потоке
3) NamedPipeServerStream.Disconnect () не работает
Непонятно, как настроить таймаут для операций чтения NamedPipeServerStream?


Позвольте представить вам пример. Спецификация IPC требует обмена строками с завершением \ 0. Клиент отправляет сообщение, сервер обрабатывает сообщение и в случае необходимости отправляет ответ. Если клиент в конце не отправляет \ 0 (клиент не наш, поэтому мы не можем гарантировать правильность его работы), метод Read будет ждать вечно, а клиент (поскольку мы его не контролируем) может ждать вечно ответ тоже.

Далее приводится упрощенный пример реализации:

    public void RestartServer()
    {
        _pipeServerThread.Interrupt();  //doesn't affect Read wait
        _pipeServerThread.Abort();      //doesn't affect Read wait
    }

    private void PipeServerRun(object o) //runs on _pipeServerThread
    {
        _pipeServer = new NamedPipeServerStream(_pipeName, InOut, 100,
                      PipeTransmissionMode.Message, PipeOptions.WriteThrough);
        //_pipeServer.ReadTimeout = 100; //System.InvalidOperationException: Timeouts are not supporte d on this stream.

        // Wait for a client to connect
        while (true)
        {
            _pipeServer.WaitForConnection();
            string request = ReadPipeString();
            //... process request, send response and disconnect
        }
    }

    /// <summary>
    /// Read a \0 terminated string from the pipe
    /// </summary>
    private string ReadPipeString()
    {
        StringBuilder builder = new StringBuilder();
        var streamReader = new StreamReader(_pipeServer);

        while (true)
        {
            //read next byte 
            char[] chars = new char[1];
            streamReader.Read(chars, 0, 1); // <- This will wait forever if no \0 and no more data from client

            if (chars[0] == '\0') return builder.ToString();
            builder.Append(chars[0]);
        }
    }

Итак, как установить тайм-аут для операций чтения NamedPipeServerStream?

8
задан MajesticRa 15 July 2011 в 17:28
поделиться