管道正在关闭异常

本文关键字:异常 管道 | 更新日期: 2023-09-27 18:22:46

有时,在某些机器上,使用我的程序的客户端会出现"管道正在关闭"异常。这种情况发生在.WWaitForConnection()上的NamedPipeServerStream上。之后,应用程序完全崩溃并释放一个windows异常。当NamedPipeClientStream将信息传输到独立应用程序时,就会发生这种情况。

主要功能:我写了几个工具(Office工具栏、一个服务、一个独立的.net应用程序和一个litle starter exe),它们与NamedPipes一起通信。该服务运行一个始终打开的NamedPipeServerStream(状态为.WWaitForConnection();)并且独立应用程序也具有NamedPipeServerStream。工具栏和starter.exe与服务通信。然后使用独立应用程序的服务。

什么样的问题可以释放正在关闭的管道异常?服务器是否可能向独立应用程序发送信息,但由于独立应用程序未准备好或其他原因而提前关闭流?在每个NamedPipeClientStream上,如果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();
    }

管道服务器(在seperad线程中运行)的示例

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();

管道正在关闭异常

我可能终于找到了问题。。

我发现在这个代码之后:

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

管道Client.IsConnected();直接返回false,因此它永远不会到达WaitForPipeDrain。我现在这样做了,希望客户端在服务器完成读取之前不要关闭连接。。

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

你认为这能解决问题吗?自从我这么做以来,我从未在两台测试机上出现过错误。但是错误很少发生。。

我的使用有点不同,但我将把服务器线程包括在内,因为它目前主要是从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();
    }