Труба закрывается Исключение - PullRequest
0 голосов
/ 07 февраля 2012

Иногда, на некоторых машинах часто и на некоторых, клиенты, которые используют мою программу, получают исключение "канал закрывается". Это происходит на NamedPipeServerStream, который находится на .WaitForConnection (). После этого приложение полностью падает и выдает исключение Windows. Это происходит, когда NamedPipeClientStream передает информацию в автономное приложение.

Основные функции: Я написал несколько Инструментов (Панели инструментов Office, Сервис, отдельное приложение .net и небольшой стартовый exe), которые взаимодействуют вместе с NamedPipes. Служба запускает NamedPipeServerStream, который всегда открыт (в состоянии .WaitForConnection ();), а у Автономного приложения также есть NamedPipeServerStream. Панели инструментов и стартер .exe взаимодействуют с сервисом. Служба с автономным приложением.

какие проблемы могут высвободить трубу закрывается за исключением? Возможно ли, что сервер отправляет информацию Автономному приложению, но закрывает поток рано, потому что Автономное приложение не готово или что-то еще? на каждом NamedPipeClientStream я делаю waitforpipedrain, если pipeClient.IsConnected, прежде чем я закрою pipeclient ..

спасибо за помощь

edit: вот пример клиентского потока

using (NamedPipeClientStream pipeClient =
        new NamedPipeClientStream(".", pipename, PipeDirection.Out))
{
    // Wait for a client to connect
    try
    {                            
        pipeClient.Connect(3000);

        // send params to the form
        using (StreamWriter sw = new StreamWriter(pipeClient))
        {
            sw.AutoFlush = true;
            sw.WriteLine(sendtext);
        }
    }
    // Catch the IOException that is raised if the pipe is
    // broken or disconnected.
    catch (Exception e)
    {
        if (sid != "")
        {
            connections.Remove(conName);
        }
        eventLog1.WriteEntry("SendText Fehler 1 " + e.Message);
    }
    finally
    {
        if (pipeClient.IsConnected)
        {
            pipeClient.WaitForPipeDrain();
        }
        pipeClient.Close();
        pipeClient.Dispose();
    }

Пример pipeserver (который работает в отдельном потоке)

NamedPipeServerStream pipeServer;
PipeSecurity pipe_security = CreateSystemIoPipeSecurity();
do
    string pipename = global::TOfficeCenter.Properties.Settings.Default.pipename;
    string aText = "";
    pipeServer = new NamedPipeServerStream(pipename, PipeDirection.In, ONE_INSTANCE, PipeTransmissionMode.Byte,
                                    PipeOptions.None, IN_BUF_SIZE, OUT_BUF_SIZE, pipe_security);
    try
    {
        // Verbindung zu TOfficeCenter.exe aufbauen
        try
        {
            IsWaiting = true;
            pipeServer.WaitForConnection();
            IsWaiting = false;

            using (StreamReader sr = new StreamReader(pipeServer))
            {
                string temp;
                while ((temp = sr.ReadLine()) != null)
                {
                    aText = aText + temp;
                }
            }

            try
            {
                if (aText == "")
                {
                    empfang(null);
                }
                else
                {
                    if (aText != "KillPipe")
                    {  // XML empfangen
                        XmlDocumentTC xml = new XmlDocumentTC();
                        xml.LoadXml(aText);
                        empfang(xml);
                    }
                }
            }
            catch (Exception)
            {
                empfang(null);
            }
        }
        catch 
{...........
}       
    }

    catch (Exception e)
    {...........
    }

} while (running);

pipeServer.Close();

Ответы [ 2 ]

0 голосов
/ 04 февраля 2016

Мое использование немного отличается, но я включу поток сервера в сумму, так как в настоящее время он в основном взламывается со страницы MSDN:

MSDN: как использовать именованные каналы

Не уверен, нужен ли мне "WaitForPipeToDrain ()", но я взял его из вашего кода:)

Я думаю, что сброс pipeServer каждый раз - это то, что очищало мойIOException.

    int threadId = Thread.CurrentThread.ManagedThreadId;
    bool sentinel = true;

    while (sentinel)
    {
        NamedPipeServerStream pipeServer =
            new NamedPipeServerStream("shapspipe", PipeDirection.InOut, 1);
        // Wait for a client to connect
        pipeServer.WaitForConnection();

        Console.WriteLine("Client connected on thread[{0}].", threadId);
        try
        {
            // Read the request from the client. Once the client has
            // written to the pipe its security token will be available.

            StreamString ss = new StreamString(pipeServer);

            // Verify our identity to the connected client using a
            // string that the client anticipates.

            ss.WriteString("I am the one true server!");
            string message = ss.ReadString();

            Console.WriteLine("received from client: " + message);

            ss.WriteString("echo from server: " + message);

            Console.WriteLine("Received from client: {0} on thread[{1}] as user: {2}.",
                message, threadId, pipeServer.GetImpersonationUserName());
        }
        // Catch the IOException that is raised if the pipe is broken
        // or disconnected.
        catch (IOException e)
        {
            Console.WriteLine("ERROR: {0}", e.Message);
        }
        pipeServer.WaitForPipeDrain();
        pipeServer.Close();
    }
0 голосов
/ 08 февраля 2012

Возможно, я наконец-то нашел проблему ..

Я узнал, что после этого кода:

                    using (StreamWriter sw = new StreamWriter(pipeClient))
                    {
                        sw.AutoFlush = true;
                        sw.WriteLine(sendtext);
                    }

pipeClient.IsConnected (); возвращает напрямую значение false, чтобы оно никогда не доходило до WaitForPipeDrain. Теперь я сделал это так и надеюсь, что клиент не закроет соединение, пока сервер не завершит чтение ..

                    using (StreamWriter sw = new StreamWriter(pipeClient))
                    {
                        sw.AutoFlush = true;
                        sw.WriteLine(sendtext);
                        pipeClient.WaitForPipeDrain();
                    }

Как вы думаете, это могло бы решить проблему? Так как я сделал это, я никогда не получал ошибку на двух тестовых машинах Но ошибки все равно случались редко ..

...